Analysis date: 2020-11-18

1 Setup

1.1 Load libraries

library(tidyverse)
library(limma)
library(ggbeeswarm)
library(MultiAssayExperiment)
library(pheatmap)
library(ggpubr)
library(readxl)
library(biomartr)
library(biomaRt)
library(Rtsne)
library(pheatmap)
select <- dplyr::select

set.seed(2020)

1.2 Load data

source("Data/Figure_layouts.R")
DIA <- readRDS("Robjects/DIA2_alldata.RData")
DIA_complete_formated <- readRDS("Robjects/DIA_complete_formated_v3.RData") 

load("Data/CLL_Proteomics_Setup.RData")
load("Data/CLL_Proteomics_LimmaProteomics.RData")
load("Robjects/pred_DIA_PG5.RData")

2 Analysis

2.1 TP53

2.1.1 TP53

message("Did we measure TP53?")
## Did we measure TP53?
any(DIA$PG.ProteinGroups=="TP53")
## [1] FALSE
message("Is TP53 present in the unfiltered dataset?")
## Is TP53 present in the unfiltered dataset?
any(DIA_complete_formated$PG.ProteinGroups=="TP53")
## [1] TRUE
DIA_complete_formated %>% filter(PG.ProteinGroups=="TP53", !is.na( log.norm.MS2Quantity)) %>%
  select(Sample, Pat_ID, log.norm.MS2Quantity, cohort, TP53)

2.1.2 BCR proteins

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1" ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_BCR, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% BCR_genes  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_BCR, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.1.2.1 No PG5

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1",
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_BCR, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics, no PG5") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% BCR_genes,
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_BCR, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.1.3 Differentially abundant proteins HiRIEF

2.1.3.1 Top 100 upregulated proteins

up_in_TP53_100 <-  
  limma_results %>% filter(mut == "SNPs_TP53", 
                           logFC > 0, fdr < 0.1) %>%
  arrange(desc(logFC)) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% up_in_TP53_100  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top 100 upregulated proteins found in DIA data"))
## 42 of the top 100 upregulated proteins found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% up_in_TP53_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_up, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% up_in_TP53_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_up, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.1.3.2 Top 100 downregulated proteins

down_in_TP53_100 <-  
  limma_results %>% filter(mut == "SNPs_TP53", 
                           logFC < 0, fdr < 0.1) %>%
  arrange(logFC) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% down_in_TP53_100  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top 100 downregulated proteins found in DIA data"))
## 65 of the top 100 downregulated proteins found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% down_in_TP53_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_down, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(TP53),PG.ProteinGroups %in% down_in_TP53_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, TP53) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(TP53 = as.factor(TP53)) %>%
  ggplot(aes(TP53, mean_down, group= TP53, fill=TP53 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.1.3.3 Heatmap of differential proteins

2.1.3.3.1 Cohorts pooled
down_in_TP53_X <-  
  limma_results %>% filter(mut == "SNPs_TP53", 
                           logFC < 0, fdr < 0.05) %>%
  arrange(logFC) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% down_in_TP53_X  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top downregulated proteins found in DIA data"))
## 39 of the top downregulated proteins found in DIA data
up_in_TP53_X <-  
  limma_results %>% filter(mut == "SNPs_TP53", 
                           logFC > 0, fdr < 0.05) %>%
  arrange(desc(logFC)) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% up_in_TP53_X  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top downregulated proteins found in DIA data"))
## 28 of the top downregulated proteins found in DIA data
TP53_diff_mx <- DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, log.norm.MS2Quantity, PG.ProteinGroups ) %>%
  pivot_wider(names_from =  Sample, values_from= log.norm.MS2Quantity ) %>%
  column_to_rownames( "PG.ProteinGroups" ) %>%
  as.matrix() 
  
TP53_diff_ann <- DIA %>% 
  filter(cohort != "Germany_1", !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, TP53, cohort, IGHV_mutated, trisomy12 ) %>%
  unique() %>%
  column_to_rownames("Sample")

TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    annotation_col = TP53_diff_ann,
    scale = "row"
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

TP53_diff_ann <- TP53_diff_ann %>% arrange(TP53)
TP53_diff_mx <- TP53_diff_mx[, rownames(TP53_diff_ann)]
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann,
    cluster_cols = FALSE
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

2.1.3.3.2 Cohorts separately
2.1.3.3.2.1 Germany
TP53_diff_mx <- DIA %>% 
  filter(cohort %in% c("Germany_2", "Germany_3") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, log.norm.MS2Quantity, PG.ProteinGroups ) %>%
  pivot_wider(names_from =  Sample, values_from= log.norm.MS2Quantity ) %>%
  column_to_rownames( "PG.ProteinGroups" ) %>%
  as.matrix() 
  
TP53_diff_ann <- DIA %>% 
  filter(cohort %in% c("Germany_2", "Germany_3") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, TP53, cohort, IGHV_mutated, trisomy12, del17p13 ) %>%
  unique() %>%
  column_to_rownames("Sample")

message("unscaled")
## unscaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    #scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

message("row scaled")
## row scaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

TP53_diff_ann <- TP53_diff_ann %>% arrange(TP53)
TP53_diff_mx <- TP53_diff_mx[, rownames(TP53_diff_ann)]
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann,
    cluster_cols = FALSE
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

2.1.3.3.2.2 Sweden
TP53_diff_mx <- DIA %>% 
  filter(cohort %in% c("Sweden_1") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, log.norm.MS2Quantity, PG.ProteinGroups ) %>%
  pivot_wider(names_from =  Sample, values_from= log.norm.MS2Quantity ) %>%
  column_to_rownames( "PG.ProteinGroups" ) %>%
  as.matrix() 
  
TP53_diff_ann <- DIA %>% 
  filter(cohort %in% c("Sweden_1") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, TP53, cohort, IGHV_mutated, trisomy12 ) %>%
  unique() %>%
  column_to_rownames("Sample")

message("unscaled")
## unscaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    #scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

message("row scaled")
## row scaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

TP53_diff_ann <- TP53_diff_ann %>% arrange(TP53)
TP53_diff_mx <- TP53_diff_mx[, rownames(TP53_diff_ann)]
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann,
    cluster_cols = FALSE
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

2.1.3.3.2.3 High risk
TP53_diff_mx <- DIA %>% 
  filter(cohort %in% c("High_risk") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, log.norm.MS2Quantity, PG.ProteinGroups ) %>%
  pivot_wider(names_from =  Sample, values_from= log.norm.MS2Quantity ) %>%
  column_to_rownames( "PG.ProteinGroups" ) %>%
  as.matrix() 
  
TP53_diff_ann <- DIA %>% 
  filter(cohort %in% c("High_risk") , !is.na(TP53),PG.ProteinGroups %in% c(up_in_TP53_X, down_in_TP53_X  ) ) %>%
  select( Sample, TP53, cohort, IGHV_mutated, trisomy12, del17p13 ) %>%
  unique() %>%
  column_to_rownames("Sample")

message("unscaled")
## unscaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    #scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

message("row scaled")
## row scaled
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

TP53_diff_ann <- TP53_diff_ann %>% arrange(TP53)
TP53_diff_mx <- TP53_diff_mx[, rownames(TP53_diff_ann)]
TP53_diff_mx %>% 
  pheatmap(
    color =  RColorBrewer::brewer.pal(100, "RdBu"),
    show_colnames = F,
    scale = "row",
    annotation_col = TP53_diff_ann,
    cluster_cols = FALSE
  )
## Warning in RColorBrewer::brewer.pal(100, "RdBu"): n too large, allowed maximum for palette RdBu is 11
## Returning the palette you asked for with that many colors

2.2 Trisomy 12

2.2.1 BCR proteins

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% BCR_genes  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_BCR, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% BCR_genes  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_BCR, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.2 Upregulation gene chr12 in trisomy 12

plot_chromosome_theme <- list(
    coord_cartesian(ylim=c(-0.8,0.8)),
    facet_wrap(~paste("chromosome",chromosome_name), scales = "free_x"),
    ylab("log2 norm. protein abundance"),
    xlab("Protein location on chromosome"),
    scale_color_manual(values=c("#0571b0", "#ca0020", "grey"))
)

Chr12_P_plot_DIA_Germany_1 <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort == "Germany_1") %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Germany_1 trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_Germany_1 +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 80 row(s) containing missing values (geom_path).

Chr12_P_plot_DIA_Germany_2 <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort == "Germany_2") %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Germany_2 trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_Germany_2 +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 240 row(s) containing missing values (geom_path).

Chr12_P_plot_DIA_Germany_3 <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort == "Germany_3") %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Germany_3 trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_Germany_3 +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'

Chr12_P_plot_DIA_Germany_2_3 <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort %in% c( "Germany_3", "Germany_2" ) ) %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Germany_2 and Germany_3 trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_Germany_2_3 +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 240 row(s) containing missing values (geom_path).

Chr12_P_plot_DIA_Sweden_1 <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort == "Sweden_1") %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Sweden_1 trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_Sweden_1 +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 320 row(s) containing missing values (geom_path).

Chr12_P_plot_DIA_High_risk <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12"), cohort == "High_risk") %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("High_risk trisomy12") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_High_risk +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 480 row(s) containing missing values (geom_path).

Chr12_P_plot_DIA_all <- 
  DIA %>%
  separate( col = PG.Locus, into = c(NA, "chromosome_name", "start_position") , sep = ":", remove = FALSE, extra = "drop" ) %>%
  filter( !is.na(log.norm.MS2Quantity), 
          chromosome_name %in% c("12")) %>%
  mutate(trisomy12 = as.factor(trisomy12),
         start_position = as.numeric(start_position)) %>%
  ggplot(aes(start_position, log.norm.MS2Quantity, group=Sample)) +
  geom_point(size=0.5, alpha=0.2, color="darkgrey") +
  stat_smooth(geom='line', alpha=0.5, se=FALSE, aes(color=trisomy12), span=0.5, method = "loess") +
  plot_chromosome_theme +
  pp_sra +
  ggtitle("Trisomy12 all cohorts") +
  geom_rect(xmin = 0, ymin=-0.78, ymax=0.78, xmax=133275309, color="gray40", size=1.5,  fill=NA)
Chr12_P_plot_DIA_all +  theme(aspect.ratio=0.4, legend.position = 'none') 
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 1120 row(s) containing missing values (geom_path).

2.2.3 Differentially abundant proteins HiRIEF

2.2.3.1 Upregulated hits

up_in_tris12_hit <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC > 0, hit_annotation == "hit" ) %>%
  .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_hit  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the upregulated hits found in DIA data"))
## 26 of the upregulated hits found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_hit  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_hit  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.3.2 Downregulated hits

down_in_tris12_hit <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC < 0, hit_annotation == "hit" ) %>%
  .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_hit  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the downregulated hits found in DIA data"))
## 4 of the downregulated hits found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_hit  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_hit  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.3.3 Upregulated candidates

up_in_tris12_cand <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC > 0, hit_annotation %in% c( "hit", "candidate") ) %>%
  .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_cand  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the upregulated hits found in DIA data"))
## 109 of the upregulated hits found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in%  up_in_tris12_cand  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in%  up_in_tris12_cand  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.3.4 Downregulated hits

down_in_tris12_cand <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC < 0, hit_annotation %in% c( "hit", "candidate") ) %>%
  .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_cand  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the downregulated hits found in DIA data"))
## 30 of the downregulated hits found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in%  down_in_tris12_cand  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in%  down_in_tris12_cand  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.3.5 Top 100 upregulated proteins

up_in_tris12_100 <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC > 0, fdr < 0.1) %>%
  arrange(desc(logFC)) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_100  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top 100 upregulated proteins found in DIA data"))
## 37 of the top 100 upregulated proteins found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% up_in_tris12_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_up = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_up, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.2.3.6 Top 100 downregulated proteins

down_in_tris12_100 <-  
  limma_results %>% filter(mut == "chrom_abber_trisomy12", 
                           logFC < 0, fdr < 0.1) %>%
  arrange(logFC) %>%
  dplyr::slice(1:100) %>% .$gene

message(paste(
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_100  ) %>% .$PG.ProteinGroups %>% unique %>% length,
"of the top 100 downregulated proteins found in DIA data"))
## 35 of the top 100 downregulated proteins found in DIA data
DIA %>% 
  filter(cohort != "Germany_1", !is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("All DIA proteomics") +
  pp_sra 
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12),PG.ProteinGroups %in% down_in_tris12_100  ) %>%
  group_by(cohort, Sample, `Sample ID`, Pat_ID, trisomy12) %>%
  summarise(mean_down = mean(log.norm.MS2Quantity, na.rm=TRUE )) %>%
  ungroup() %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_down, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  pp_sra +
  facet_wrap(~cohort)
## `summarise()` regrouping output by 'cohort', 'Sample', 'Sample ID', 'Pat_ID' (override with `.groups` argument)

2.3 IGHV

2.3.1 ZAP70

############ Germany_1
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70", cohort == "Germany_1"  ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics Germany_1") +
  pp_sra

message("Number of NAs DIA Germany_1:")
## Number of NAs DIA Germany_1:
DIA %>% 
  filter(!is.na(IGHV_mutated), cohort == "Germany_1",PG.ProteinGroups =="ZAP70"  ) %>% 
  select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)
############ Germany_2
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70", cohort == "Germany_2"  ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics Germany_2") +
  pp_sra

message("Number of NAs DIA Germany_2:")
## Number of NAs DIA Germany_2:
DIA %>% 
  filter(!is.na(IGHV_mutated), cohort == "Germany_2",PG.ProteinGroups =="ZAP70"  ) %>% select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)
############ Germany_3
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70", cohort == "Germany_3"  ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics Germany_3") +
  pp_sra

message("Number of NAs DIA Germany_3:")
## Number of NAs DIA Germany_3:
DIA %>% 
  filter(!is.na(IGHV_mutated), cohort == "Germany_3",PG.ProteinGroups =="ZAP70"  ) %>% select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)
############ Sweden
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70", cohort == "Sweden_1"  ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics Sweden_1") +
  pp_sra

message("Number of NAs DIA Sweden_1:")
## Number of NAs DIA Sweden_1:
DIA %>% 
  filter(!is.na(IGHV_mutated), cohort == "Sweden_1",PG.ProteinGroups =="ZAP70"  ) %>% select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)
############ High risk
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70", cohort == "High_risk"  ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics High_risk") +
  pp_sra

message("Number of NAs DIA High_risk:")
## Number of NAs DIA High_risk:
DIA %>% 
  filter(!is.na(IGHV_mutated), cohort == "High_risk",PG.ProteinGroups =="ZAP70"  ) %>% select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)
############ all
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70" ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, log.norm.MS2Quantity, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("DIA proteomics all") +
  pp_sra

message("Number of NAs DIA all")
## Number of NAs DIA all
DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups =="ZAP70"  ) %>% select(IGHV_mutated, Sample, log.norm.MS2Quantity) %>% unique %>% group_by(IGHV_mutated) %>% summarise(NAs=sum(is.na(log.norm.MS2Quantity)) )
## `summarise()` ungrouping output (override with `.groups` argument)

2.3.2 BCR proteins

DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups %in% BCR_genes) %>%
  group_by(Sample, IGHV_mutated, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, mean_BCR, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ IGHV") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(IGHV_mutated),PG.ProteinGroups %in% BCR_genes) %>%
  group_by(Sample, IGHV_mutated, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  ggplot(aes(IGHV_mutated, mean_BCR, group= IGHV_mutated, fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "wilcox") +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ IGHV") +
  facet_wrap(~cohort) +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated' (override with `.groups` argument)

2.4 IGHV + trisomy12

2.4.1 BCR proteins

DIA %>% 
  filter(!is.na(IGHV_mutated),!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1") %>%
  group_by(Sample, IGHV_mutated,trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(interaction(IGHV_mutated, trisomy12), mean_BCR, group= interaction(IGHV_mutated, trisomy12), fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means() +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ IGHV + trisomy12") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated', 'trisomy12' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(IGHV_mutated),!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes) %>%
  group_by(Sample, IGHV_mutated, trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(interaction(IGHV_mutated, trisomy12), mean_BCR, group= interaction(IGHV_mutated, trisomy12), fill=IGHV_mutated )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means() +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ IGHV + trisomy12") +
  facet_wrap(~cohort) +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated', 'trisomy12' (override with `.groups` argument)

2.4.1.1 no TP53 or del17p13 and no PG5

DIA %>% 
  filter(!is.na(IGHV_mutated),!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1", 
         (is.na(TP53) | TP53== 0), (is.na(del17p13) | del17p13== 0),
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(Sample, IGHV_mutated,trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  mutate("trisomy12 + IGHV" =  if_else(trisomy12 ==1 & IGHV_mutated == 1, "trisomy12 M-CLL", 
                                       if_else(trisomy12 ==1 & IGHV_mutated == 0, "trisomy12 U-CLL", 
                                                if_else(trisomy12 ==0 & IGHV_mutated == 1, "wt M-CLL", 
                                                         if_else(trisomy12 ==0 & IGHV_mutated == 0, "wt U-CLL", "NA")  ) ) ) ) %>%
  ggplot(aes(`trisomy12 + IGHV`, mean_BCR, group= `trisomy12 + IGHV`, fill=`trisomy12 + IGHV` )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "t.test", 
                     comparisons = list( c("wt M-CLL", "wt U-CLL"), c( "trisomy12 U-CLL", "wt U-CLL" ),
                                           c( "trisomy12 M-CLL", "wt M-CLL" ) ) ) +
  #scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  scale_fill_manual(values=colors_CCP[1:4]) +
  ggtitle("BCR protein abundances ~ IGHV + trisomy12 no PG5 or TP53/del17p") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated', 'trisomy12' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(IGHV_mutated),!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1", 
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(Sample, IGHV_mutated,trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  mutate("trisomy12 + IGHV" =  if_else(trisomy12 ==1 & IGHV_mutated == 1, "trisomy12 M-CLL", 
                                       if_else(trisomy12 ==1 & IGHV_mutated == 0, "trisomy12 U-CLL", 
                                                if_else(trisomy12 ==0 & IGHV_mutated == 1, "wt M-CLL", 
                                                         if_else(trisomy12 ==0 & IGHV_mutated == 0, "wt U-CLL", "NA")  ) ) ) ) %>%
  ggplot(aes(`trisomy12 + IGHV`, mean_BCR, group= `trisomy12 + IGHV`, fill=`trisomy12 + IGHV` )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "t.test", 
                     comparisons = list( c("wt M-CLL", "wt U-CLL"), c( "trisomy12 U-CLL", "wt U-CLL" ),
                                           c( "trisomy12 M-CLL", "wt M-CLL" ) ) ) +
  #scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  scale_fill_manual(values=colors_CCP[1:4]) +
  ggtitle("BCR protein abundances ~ IGHV + trisomy12 no PG5") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated', 'trisomy12' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(IGHV_mutated),!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1", 
         cohort != "High_risk",
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(Sample, IGHV_mutated,trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(IGHV_mutated = as.factor(IGHV_mutated)) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  mutate("trisomy12 + IGHV" =  if_else(trisomy12 ==1 & IGHV_mutated == 1, "trisomy12 M-CLL", 
                                       if_else(trisomy12 ==1 & IGHV_mutated == 0, "trisomy12 U-CLL", 
                                                if_else(trisomy12 ==0 & IGHV_mutated == 1, "wt M-CLL", 
                                                         if_else(trisomy12 ==0 & IGHV_mutated == 0, "wt U-CLL", "NA")  ) ) ) ) %>%
  ggplot(aes(`trisomy12 + IGHV`, mean_BCR, group= `trisomy12 + IGHV`, fill=`trisomy12 + IGHV` )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "t.test", 
                     comparisons = list( c("wt M-CLL", "wt U-CLL"), c( "trisomy12 U-CLL", "wt U-CLL" ),
                                           c( "trisomy12 M-CLL", "wt M-CLL" ) ) ) +
  #scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  scale_fill_manual(values=colors_CCP[1:4]) +
  ggtitle("BCR protein abundances ~ IGHV + trisomy12 no PG5 and High risk") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'IGHV_mutated', 'trisomy12' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1", 
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(Sample, trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_BCR, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "t.test" ) +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ trisomy12 no PG5") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'trisomy12' (override with `.groups` argument)

DIA %>% 
  filter(!is.na(trisomy12), PG.ProteinGroups %in% BCR_genes, cohort != "Germany_1", 
         (is.na(TP53) | TP53== 0), (is.na(del17p13) | del17p13== 0),
         !Sample %in% (pred_DIA_PG5 %>% filter(PG5_predicted_ktsp == TRUE) %>% .$Sample ) ) %>%
  group_by(Sample, trisomy12, cohort) %>%
  summarise(mean_BCR = mean(log.norm.MS2Quantity, na.rm= TRUE) ) %>%
  mutate(trisomy12 = as.factor(trisomy12)) %>%
  ggplot(aes(trisomy12, mean_BCR, group= trisomy12, fill=trisomy12 )) +
  geom_boxplot() +
  geom_beeswarm() +
  stat_compare_means(method = "t.test" ) +
  scale_fill_manual(values=c("#0571b0", "#ca0020", "grey")) +
  ggtitle("BCR protein abundances ~ trisomy12 no PG5 or TP53/del17p") +
  pp_sra
## `summarise()` regrouping output by 'Sample', 'trisomy12' (override with `.groups` argument)

3 Session Info

sessionInfo()
## R version 4.0.2 (2020-06-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Catalina 10.15.6
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] parallel  stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] Rtsne_0.15                  biomaRt_2.44.1             
##  [3] biomartr_0.9.2              readxl_1.3.1               
##  [5] ggpubr_0.4.0                pheatmap_1.0.12            
##  [7] MultiAssayExperiment_1.14.0 SummarizedExperiment_1.18.2
##  [9] DelayedArray_0.14.1         matrixStats_0.56.0         
## [11] Biobase_2.48.0              GenomicRanges_1.40.0       
## [13] GenomeInfoDb_1.24.2         IRanges_2.22.2             
## [15] S4Vectors_0.26.1            BiocGenerics_0.34.0        
## [17] ggbeeswarm_0.6.0            limma_3.44.3               
## [19] forcats_0.5.0               stringr_1.4.0              
## [21] dplyr_1.0.2                 purrr_0.3.4                
## [23] readr_1.3.1                 tidyr_1.1.2                
## [25] tibble_3.0.3                ggplot2_3.3.2              
## [27] tidyverse_1.3.0             BiocStyle_2.16.0           
## 
## loaded via a namespace (and not attached):
##  [1] colorspace_1.4-1       ggsignif_0.6.0         ellipsis_0.3.1        
##  [4] rio_0.5.16             XVector_0.28.0         base64enc_0.1-3       
##  [7] fs_1.5.0               rstudioapi_0.11        farver_2.0.3          
## [10] bit64_4.0.5            AnnotationDbi_1.50.3   fansi_0.4.1           
## [13] lubridate_1.7.9        xml2_1.3.2             splines_4.0.2         
## [16] knitr_1.29             jsonlite_1.7.1         broom_0.7.0           
## [19] dbplyr_1.4.4           BiocManager_1.30.10    compiler_4.0.2        
## [22] httr_1.4.2             backports_1.1.9        assertthat_0.2.1      
## [25] Matrix_1.2-18          cli_2.0.2              htmltools_0.5.0       
## [28] prettyunits_1.1.1      tools_4.0.2            gtable_0.3.0          
## [31] glue_1.4.2             GenomeInfoDbData_1.2.3 rappdirs_0.3.1        
## [34] Rcpp_1.0.5             carData_3.0-4          cellranger_1.1.0      
## [37] vctrs_0.3.4            Biostrings_2.56.0      nlme_3.1-149          
## [40] xfun_0.17              openxlsx_4.1.5         rvest_0.3.6           
## [43] lifecycle_0.2.0        rstatix_0.6.0          XML_3.99-0.5          
## [46] zlibbioc_1.34.0        scales_1.1.1           hms_0.5.3             
## [49] RColorBrewer_1.1-2     yaml_2.2.1             curl_4.3              
## [52] memoise_1.1.0          stringi_1.5.3          RSQLite_2.2.0         
## [55] zip_2.1.1              rlang_0.4.7            pkgconfig_2.0.3       
## [58] bitops_1.0-6           evaluate_0.14          lattice_0.20-41       
## [61] labeling_0.3           bit_4.0.4              tidyselect_1.1.0      
## [64] magrittr_1.5           bookdown_0.20          R6_2.4.1              
## [67] magick_2.4.0           generics_0.0.2         DBI_1.1.0             
## [70] mgcv_1.8-33            pillar_1.4.6           haven_2.3.1           
## [73] foreign_0.8-80         withr_2.2.0            abind_1.4-5           
## [76] RCurl_1.98-1.2         modelr_0.1.8           crayon_1.3.4          
## [79] car_3.0-9              BiocFileCache_1.12.1   rmarkdown_2.3         
## [82] progress_1.2.2         grid_4.0.2             data.table_1.13.0     
## [85] blob_1.2.1             reprex_0.3.0           digest_0.6.25         
## [88] openssl_1.4.2          munsell_0.5.0          beeswarm_0.2.3        
## [91] vipor_0.4.5            askpass_1.1
knitr::knit_exit()
LS0tCnRpdGxlOiAiRElBOiBBc3NvY2lhdGlvbiBiZXR3ZWVuIHByb3RlaW4gYWJ1bmRhbmNlIGFuZCBnZW5ldGljcyIKYXV0aG9yOiAiU29waGllIEhlcmJzdCIKb3V0cHV0OgogIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogeWVzCiAgICBkZl9wcmludDogcGFnZWQKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCkFuYWx5c2lzIGRhdGU6IGByIFN5cy5EYXRlKClgCgojIFNldHVwCiMjIExvYWQgbGlicmFyaWVzCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsaW1tYSkKbGlicmFyeShnZ2JlZXN3YXJtKQpsaWJyYXJ5KE11bHRpQXNzYXlFeHBlcmltZW50KQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoYmlvbWFydHIpCmxpYnJhcnkoYmlvbWFSdCkKbGlicmFyeShSdHNuZSkKbGlicmFyeShwaGVhdG1hcCkKc2VsZWN0IDwtIGRwbHlyOjpzZWxlY3QKCnNldC5zZWVkKDIwMjApCmBgYAoKIyMgTG9hZCBkYXRhCmBgYHtyfQpzb3VyY2UoIkRhdGEvRmlndXJlX2xheW91dHMuUiIpCkRJQSA8LSByZWFkUkRTKCJSb2JqZWN0cy9ESUEyX2FsbGRhdGEuUkRhdGEiKQpESUFfY29tcGxldGVfZm9ybWF0ZWQgPC0gcmVhZFJEUygiUm9iamVjdHMvRElBX2NvbXBsZXRlX2Zvcm1hdGVkX3YzLlJEYXRhIikgCgpsb2FkKCJEYXRhL0NMTF9Qcm90ZW9taWNzX1NldHVwLlJEYXRhIikKbG9hZCgiRGF0YS9DTExfUHJvdGVvbWljc19MaW1tYVByb3Rlb21pY3MuUkRhdGEiKQpsb2FkKCJSb2JqZWN0cy9wcmVkX0RJQV9QRzUuUkRhdGEiKQpgYGAKCiMgQW5hbHlzaXMKIyMgVFA1MwojIyMgVFA1MwpgYGB7cn0KbWVzc2FnZSgiRGlkIHdlIG1lYXN1cmUgVFA1Mz8iKQphbnkoRElBJFBHLlByb3RlaW5Hcm91cHM9PSJUUDUzIikKCm1lc3NhZ2UoIklzIFRQNTMgcHJlc2VudCBpbiB0aGUgdW5maWx0ZXJlZCBkYXRhc2V0PyIpCmFueShESUFfY29tcGxldGVfZm9ybWF0ZWQkUEcuUHJvdGVpbkdyb3Vwcz09IlRQNTMiKQoKRElBX2NvbXBsZXRlX2Zvcm1hdGVkICU+JSBmaWx0ZXIoUEcuUHJvdGVpbkdyb3Vwcz09IlRQNTMiLCAhaXMubmEoIGxvZy5ub3JtLk1TMlF1YW50aXR5KSkgJT4lCiAgc2VsZWN0KFNhbXBsZSwgUGF0X0lELCBsb2cubm9ybS5NUzJRdWFudGl0eSwgY29ob3J0LCBUUDUzKQoKYGBgCgojIyMgQkNSIHByb3RlaW5zCmBgYHtyfQpESUEgJT4lIAogIGZpbHRlcighaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcywgY29ob3J0ICE9ICJHZXJtYW55XzEiICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIFRQNTMpICU+JQogIHN1bW1hcmlzZShtZWFuX0JDUiA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShUUDUzID0gYXMuZmFjdG9yKFRQNTMpKSAlPiUKICBnZ3Bsb3QoYWVzKFRQNTMsIG1lYW5fQkNSLCBncm91cD0gVFA1MywgZmlsbD1UUDUzICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcyIpICsKICBwcF9zcmEgCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcyAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgVFA1MykgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09VFJVRSApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKFRQNTMgPSBhcy5mYWN0b3IoVFA1MykpICU+JQogIGdncGxvdChhZXMoVFA1MywgbWVhbl9CQ1IsIGdyb3VwPSBUUDUzLCBmaWxsPVRQNTMgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgcHBfc3JhICsKICBmYWNldF93cmFwKH5jb2hvcnQpCmBgYAoKIyMjIyBObyBQRzUKYGBge3J9CkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgQkNSX2dlbmVzLCBjb2hvcnQgIT0gIkdlcm1hbnlfMSIsCiAgICAgICAgICFTYW1wbGUgJWluJSAocHJlZF9ESUFfUEc1ICU+JSBmaWx0ZXIoUEc1X3ByZWRpY3RlZF9rdHNwID09IFRSVUUpICU+JSAuJFNhbXBsZSApICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIFRQNTMpICU+JQogIHN1bW1hcmlzZShtZWFuX0JDUiA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShUUDUzID0gYXMuZmFjdG9yKFRQNTMpKSAlPiUKICBnZ3Bsb3QoYWVzKFRQNTMsIG1lYW5fQkNSLCBncm91cD0gVFA1MywgZmlsbD1UUDUzICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcywgbm8gUEc1IikgKwogIHBwX3NyYSAKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgQkNSX2dlbmVzLAogICAgICAgICAhU2FtcGxlICVpbiUgKHByZWRfRElBX1BHNSAlPiUgZmlsdGVyKFBHNV9wcmVkaWN0ZWRfa3RzcCA9PSBUUlVFKSAlPiUgLiRTYW1wbGUgKSApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCBUUDUzKSAlPiUKICBzdW1tYXJpc2UobWVhbl9CQ1IgPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoVFA1MyA9IGFzLmZhY3RvcihUUDUzKSkgJT4lCiAgZ2dwbG90KGFlcyhUUDUzLCBtZWFuX0JDUiwgZ3JvdXA9IFRQNTMsIGZpbGw9VFA1MyApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBwcF9zcmEgKwogIGZhY2V0X3dyYXAofmNvaG9ydCkKYGBgCgojIyMgRGlmZmVyZW50aWFsbHkgYWJ1bmRhbnQgcHJvdGVpbnMgSGlSSUVGCiMjIyMgVG9wIDEwMCB1cHJlZ3VsYXRlZCBwcm90ZWlucwpgYGB7cn0KdXBfaW5fVFA1M18xMDAgPC0gIAogIGxpbW1hX3Jlc3VsdHMgJT4lIGZpbHRlcihtdXQgPT0gIlNOUHNfVFA1MyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dGQyA+IDAsIGZkciA8IDAuMSkgJT4lCiAgYXJyYW5nZShkZXNjKGxvZ0ZDKSkgJT4lCiAgZHBseXI6OnNsaWNlKDE6MTAwKSAlPiUgLiRnZW5lCgptZXNzYWdlKHBhc3RlKApESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fVFA1M18xMDAgICkgJT4lIC4kUEcuUHJvdGVpbkdyb3VwcyAlPiUgdW5pcXVlICU+JSBsZW5ndGgsCiJvZiB0aGUgdG9wIDEwMCB1cHJlZ3VsYXRlZCBwcm90ZWlucyBmb3VuZCBpbiBESUEgZGF0YSIpKQoKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIHVwX2luX1RQNTNfMTAwICApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCBUUDUzKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShUUDUzID0gYXMuZmFjdG9yKFRQNTMpKSAlPiUKICBnZ3Bsb3QoYWVzKFRQNTMsIG1lYW5fdXAsIGdyb3VwPSBUUDUzLCBmaWxsPVRQNTMgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiQWxsIERJQSBwcm90ZW9taWNzIikgKwogIHBwX3NyYSAKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fVFA1M18xMDAgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIFRQNTMpICU+JQogIHN1bW1hcmlzZShtZWFuX3VwID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09VFJVRSApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKFRQNTMgPSBhcy5mYWN0b3IoVFA1MykpICU+JQogIGdncGxvdChhZXMoVFA1MywgbWVhbl91cCwgZ3JvdXA9IFRQNTMsIGZpbGw9VFA1MyApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBwcF9zcmEgKwogIGZhY2V0X3dyYXAofmNvaG9ydCkKYGBgCgoKIyMjIyBUb3AgMTAwIGRvd25yZWd1bGF0ZWQgcHJvdGVpbnMKYGBge3J9CmRvd25faW5fVFA1M18xMDAgPC0gIAogIGxpbW1hX3Jlc3VsdHMgJT4lIGZpbHRlcihtdXQgPT0gIlNOUHNfVFA1MyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dGQyA8IDAsIGZkciA8IDAuMSkgJT4lCiAgYXJyYW5nZShsb2dGQykgJT4lCiAgZHBseXI6OnNsaWNlKDE6MTAwKSAlPiUgLiRnZW5lCgptZXNzYWdlKHBhc3RlKApESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgZG93bl9pbl9UUDUzXzEwMCAgKSAlPiUgLiRQRy5Qcm90ZWluR3JvdXBzICU+JSB1bmlxdWUgJT4lIGxlbmd0aCwKIm9mIHRoZSB0b3AgMTAwIGRvd25yZWd1bGF0ZWQgcHJvdGVpbnMgZm91bmQgaW4gRElBIGRhdGEiKSkKCkRJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAhPSAiR2VybWFueV8xIiwgIWlzLm5hKFRQNTMpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBkb3duX2luX1RQNTNfMTAwICApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCBUUDUzKSAlPiUKICBzdW1tYXJpc2UobWVhbl9kb3duID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09VFJVRSApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKFRQNTMgPSBhcy5mYWN0b3IoVFA1MykpICU+JQogIGdncGxvdChhZXMoVFA1MywgbWVhbl9kb3duLCBncm91cD0gVFA1MywgZmlsbD1UUDUzICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcyIpICsKICBwcF9zcmEgCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIGRvd25faW5fVFA1M18xMDAgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIFRQNTMpICU+JQogIHN1bW1hcmlzZShtZWFuX2Rvd24gPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoVFA1MyA9IGFzLmZhY3RvcihUUDUzKSkgJT4lCiAgZ2dwbG90KGFlcyhUUDUzLCBtZWFuX2Rvd24sIGdyb3VwPSBUUDUzLCBmaWxsPVRQNTMgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgcHBfc3JhICsKICBmYWNldF93cmFwKH5jb2hvcnQpCmBgYAoKIyMjIyBIZWF0bWFwIG9mIGRpZmZlcmVudGlhbCBwcm90ZWlucwojIyMjIyBDb2hvcnRzIHBvb2xlZApgYGB7cn0KZG93bl9pbl9UUDUzX1ggPC0gIAogIGxpbW1hX3Jlc3VsdHMgJT4lIGZpbHRlcihtdXQgPT0gIlNOUHNfVFA1MyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dGQyA8IDAsIGZkciA8IDAuMDUpICU+JQogIGFycmFuZ2UobG9nRkMpICU+JQogIGRwbHlyOjpzbGljZSgxOjEwMCkgJT4lIC4kZ2VuZQoKbWVzc2FnZShwYXN0ZSgKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIGRvd25faW5fVFA1M19YICApICU+JSAuJFBHLlByb3RlaW5Hcm91cHMgJT4lIHVuaXF1ZSAlPiUgbGVuZ3RoLAoib2YgdGhlIHRvcCBkb3ducmVndWxhdGVkIHByb3RlaW5zIGZvdW5kIGluIERJQSBkYXRhIikpCgp1cF9pbl9UUDUzX1ggPC0gIAogIGxpbW1hX3Jlc3VsdHMgJT4lIGZpbHRlcihtdXQgPT0gIlNOUHNfVFA1MyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dGQyA+IDAsIGZkciA8IDAuMDUpICU+JQogIGFycmFuZ2UoZGVzYyhsb2dGQykpICU+JQogIGRwbHlyOjpzbGljZSgxOjEwMCkgJT4lIC4kZ2VuZQoKbWVzc2FnZShwYXN0ZSgKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIHVwX2luX1RQNTNfWCAgKSAlPiUgLiRQRy5Qcm90ZWluR3JvdXBzICU+JSB1bmlxdWUgJT4lIGxlbmd0aCwKIm9mIHRoZSB0b3AgZG93bnJlZ3VsYXRlZCBwcm90ZWlucyBmb3VuZCBpbiBESUEgZGF0YSIpKQoKVFA1M19kaWZmX214IDwtIERJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAhPSAiR2VybWFueV8xIiwgIWlzLm5hKFRQNTMpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBjKHVwX2luX1RQNTNfWCwgZG93bl9pbl9UUDUzX1ggICkgKSAlPiUKICBzZWxlY3QoIFNhbXBsZSwgbG9nLm5vcm0uTVMyUXVhbnRpdHksIFBHLlByb3RlaW5Hcm91cHMgKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gIFNhbXBsZSwgdmFsdWVzX2Zyb209IGxvZy5ub3JtLk1TMlF1YW50aXR5ICkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCAiUEcuUHJvdGVpbkdyb3VwcyIgKSAlPiUKICBhcy5tYXRyaXgoKSAKICAKVFA1M19kaWZmX2FubiA8LSBESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgYyh1cF9pbl9UUDUzX1gsIGRvd25faW5fVFA1M19YICApICkgJT4lCiAgc2VsZWN0KCBTYW1wbGUsIFRQNTMsIGNvaG9ydCwgSUdIVl9tdXRhdGVkLCB0cmlzb215MTIgKSAlPiUKICB1bmlxdWUoKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoIlNhbXBsZSIpCgpUUDUzX2RpZmZfbXggJT4lIAogIHBoZWF0bWFwKAogICAgY29sb3IgPSAgUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDEwMCwgIlJkQnUiKSwKICAgIHNob3dfY29sbmFtZXMgPSBGLAogICAgYW5ub3RhdGlvbl9jb2wgPSBUUDUzX2RpZmZfYW5uLAogICAgc2NhbGUgPSAicm93IgogICkKClRQNTNfZGlmZl9hbm4gPC0gVFA1M19kaWZmX2FubiAlPiUgYXJyYW5nZShUUDUzKQpUUDUzX2RpZmZfbXggPC0gVFA1M19kaWZmX214Wywgcm93bmFtZXMoVFA1M19kaWZmX2FubildClRQNTNfZGlmZl9teCAlPiUgCiAgcGhlYXRtYXAoCiAgICBjb2xvciA9ICBSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoMTAwLCAiUmRCdSIpLAogICAgc2hvd19jb2xuYW1lcyA9IEYsCiAgICBzY2FsZSA9ICJyb3ciLAogICAgYW5ub3RhdGlvbl9jb2wgPSBUUDUzX2RpZmZfYW5uLAogICAgY2x1c3Rlcl9jb2xzID0gRkFMU0UKICApCmBgYAoKIyMjIyMgQ29ob3J0cyBzZXBhcmF0ZWx5CiMjIyMjIyBHZXJtYW55CmBgYHtyfQpUUDUzX2RpZmZfbXggPC0gRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICVpbiUgYygiR2VybWFueV8yIiwgIkdlcm1hbnlfMyIpICwgIWlzLm5hKFRQNTMpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBjKHVwX2luX1RQNTNfWCwgZG93bl9pbl9UUDUzX1ggICkgKSAlPiUKICBzZWxlY3QoIFNhbXBsZSwgbG9nLm5vcm0uTVMyUXVhbnRpdHksIFBHLlByb3RlaW5Hcm91cHMgKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gIFNhbXBsZSwgdmFsdWVzX2Zyb209IGxvZy5ub3JtLk1TMlF1YW50aXR5ICkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCAiUEcuUHJvdGVpbkdyb3VwcyIgKSAlPiUKICBhcy5tYXRyaXgoKSAKICAKVFA1M19kaWZmX2FubiA8LSBESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgJWluJSBjKCJHZXJtYW55XzIiLCAiR2VybWFueV8zIikgLCAhaXMubmEoVFA1MyksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIGModXBfaW5fVFA1M19YLCBkb3duX2luX1RQNTNfWCAgKSApICU+JQogIHNlbGVjdCggU2FtcGxlLCBUUDUzLCBjb2hvcnQsIElHSFZfbXV0YXRlZCwgdHJpc29teTEyLCBkZWwxN3AxMyApICU+JQogIHVuaXF1ZSgpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygiU2FtcGxlIikKCm1lc3NhZ2UoInVuc2NhbGVkIikKVFA1M19kaWZmX214ICU+JSAKICBwaGVhdG1hcCgKICAgIGNvbG9yID0gIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCgxMDAsICJSZEJ1IiksCiAgICBzaG93X2NvbG5hbWVzID0gRiwKICAgICNzY2FsZSA9ICJyb3ciLAogICAgYW5ub3RhdGlvbl9jb2wgPSBUUDUzX2RpZmZfYW5uCiAgKQoKbWVzc2FnZSgicm93IHNjYWxlZCIpClRQNTNfZGlmZl9teCAlPiUgCiAgcGhlYXRtYXAoCiAgICBjb2xvciA9ICBSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoMTAwLCAiUmRCdSIpLAogICAgc2hvd19jb2xuYW1lcyA9IEYsCiAgICBzY2FsZSA9ICJyb3ciLAogICAgYW5ub3RhdGlvbl9jb2wgPSBUUDUzX2RpZmZfYW5uCiAgKQoKVFA1M19kaWZmX2FubiA8LSBUUDUzX2RpZmZfYW5uICU+JSBhcnJhbmdlKFRQNTMpClRQNTNfZGlmZl9teCA8LSBUUDUzX2RpZmZfbXhbLCByb3duYW1lcyhUUDUzX2RpZmZfYW5uKV0KVFA1M19kaWZmX214ICU+JSAKICBwaGVhdG1hcCgKICAgIGNvbG9yID0gIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCgxMDAsICJSZEJ1IiksCiAgICBzaG93X2NvbG5hbWVzID0gRiwKICAgIHNjYWxlID0gInJvdyIsCiAgICBhbm5vdGF0aW9uX2NvbCA9IFRQNTNfZGlmZl9hbm4sCiAgICBjbHVzdGVyX2NvbHMgPSBGQUxTRQogICkKYGBgCgojIyMjIyMgU3dlZGVuCmBgYHtyfQpUUDUzX2RpZmZfbXggPC0gRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICVpbiUgYygiU3dlZGVuXzEiKSAsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgYyh1cF9pbl9UUDUzX1gsIGRvd25faW5fVFA1M19YICApICkgJT4lCiAgc2VsZWN0KCBTYW1wbGUsIGxvZy5ub3JtLk1TMlF1YW50aXR5LCBQRy5Qcm90ZWluR3JvdXBzICkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9ICBTYW1wbGUsIHZhbHVlc19mcm9tPSBsb2cubm9ybS5NUzJRdWFudGl0eSApICU+JQogIGNvbHVtbl90b19yb3duYW1lcyggIlBHLlByb3RlaW5Hcm91cHMiICkgJT4lCiAgYXMubWF0cml4KCkgCiAgClRQNTNfZGlmZl9hbm4gPC0gRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICVpbiUgYygiU3dlZGVuXzEiKSAsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgYyh1cF9pbl9UUDUzX1gsIGRvd25faW5fVFA1M19YICApICkgJT4lCiAgc2VsZWN0KCBTYW1wbGUsIFRQNTMsIGNvaG9ydCwgSUdIVl9tdXRhdGVkLCB0cmlzb215MTIgKSAlPiUKICB1bmlxdWUoKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoIlNhbXBsZSIpCgptZXNzYWdlKCJ1bnNjYWxlZCIpClRQNTNfZGlmZl9teCAlPiUgCiAgcGhlYXRtYXAoCiAgICBjb2xvciA9ICBSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoMTAwLCAiUmRCdSIpLAogICAgc2hvd19jb2xuYW1lcyA9IEYsCiAgICAjc2NhbGUgPSAicm93IiwKICAgIGFubm90YXRpb25fY29sID0gVFA1M19kaWZmX2FubgogICkKCm1lc3NhZ2UoInJvdyBzY2FsZWQiKQpUUDUzX2RpZmZfbXggJT4lIAogIHBoZWF0bWFwKAogICAgY29sb3IgPSAgUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDEwMCwgIlJkQnUiKSwKICAgIHNob3dfY29sbmFtZXMgPSBGLAogICAgc2NhbGUgPSAicm93IiwKICAgIGFubm90YXRpb25fY29sID0gVFA1M19kaWZmX2FubgogICkKClRQNTNfZGlmZl9hbm4gPC0gVFA1M19kaWZmX2FubiAlPiUgYXJyYW5nZShUUDUzKQpUUDUzX2RpZmZfbXggPC0gVFA1M19kaWZmX214Wywgcm93bmFtZXMoVFA1M19kaWZmX2FubildClRQNTNfZGlmZl9teCAlPiUgCiAgcGhlYXRtYXAoCiAgICBjb2xvciA9ICBSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoMTAwLCAiUmRCdSIpLAogICAgc2hvd19jb2xuYW1lcyA9IEYsCiAgICBzY2FsZSA9ICJyb3ciLAogICAgYW5ub3RhdGlvbl9jb2wgPSBUUDUzX2RpZmZfYW5uLAogICAgY2x1c3Rlcl9jb2xzID0gRkFMU0UKICApCmBgYAoKIyMjIyMjIEhpZ2ggcmlzawpgYGB7cn0KVFA1M19kaWZmX214IDwtIERJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAlaW4lIGMoIkhpZ2hfcmlzayIpICwgIWlzLm5hKFRQNTMpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBjKHVwX2luX1RQNTNfWCwgZG93bl9pbl9UUDUzX1ggICkgKSAlPiUKICBzZWxlY3QoIFNhbXBsZSwgbG9nLm5vcm0uTVMyUXVhbnRpdHksIFBHLlByb3RlaW5Hcm91cHMgKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gIFNhbXBsZSwgdmFsdWVzX2Zyb209IGxvZy5ub3JtLk1TMlF1YW50aXR5ICkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCAiUEcuUHJvdGVpbkdyb3VwcyIgKSAlPiUKICBhcy5tYXRyaXgoKSAKICAKVFA1M19kaWZmX2FubiA8LSBESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgJWluJSBjKCJIaWdoX3Jpc2siKSAsICFpcy5uYShUUDUzKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgYyh1cF9pbl9UUDUzX1gsIGRvd25faW5fVFA1M19YICApICkgJT4lCiAgc2VsZWN0KCBTYW1wbGUsIFRQNTMsIGNvaG9ydCwgSUdIVl9tdXRhdGVkLCB0cmlzb215MTIsIGRlbDE3cDEzICkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJTYW1wbGUiKQoKbWVzc2FnZSgidW5zY2FsZWQiKQpUUDUzX2RpZmZfbXggJT4lIAogIHBoZWF0bWFwKAogICAgY29sb3IgPSAgUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDEwMCwgIlJkQnUiKSwKICAgIHNob3dfY29sbmFtZXMgPSBGLAogICAgI3NjYWxlID0gInJvdyIsCiAgICBhbm5vdGF0aW9uX2NvbCA9IFRQNTNfZGlmZl9hbm4KICApCgptZXNzYWdlKCJyb3cgc2NhbGVkIikKVFA1M19kaWZmX214ICU+JSAKICBwaGVhdG1hcCgKICAgIGNvbG9yID0gIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCgxMDAsICJSZEJ1IiksCiAgICBzaG93X2NvbG5hbWVzID0gRiwKICAgIHNjYWxlID0gInJvdyIsCiAgICBhbm5vdGF0aW9uX2NvbCA9IFRQNTNfZGlmZl9hbm4KICApCgpUUDUzX2RpZmZfYW5uIDwtIFRQNTNfZGlmZl9hbm4gJT4lIGFycmFuZ2UoVFA1MykKVFA1M19kaWZmX214IDwtIFRQNTNfZGlmZl9teFssIHJvd25hbWVzKFRQNTNfZGlmZl9hbm4pXQpUUDUzX2RpZmZfbXggJT4lIAogIHBoZWF0bWFwKAogICAgY29sb3IgPSAgUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDEwMCwgIlJkQnUiKSwKICAgIHNob3dfY29sbmFtZXMgPSBGLAogICAgc2NhbGUgPSAicm93IiwKICAgIGFubm90YXRpb25fY29sID0gVFA1M19kaWZmX2FubiwKICAgIGNsdXN0ZXJfY29scyA9IEZBTFNFCiAgKQpgYGAKCiMjIFRyaXNvbXkgMTIKIyMjIEJDUiBwcm90ZWlucwpgYGB7cn0KRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcyAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl9CQ1IgPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIGdncGxvdChhZXModHJpc29teTEyLCBtZWFuX0JDUiwgZ3JvdXA9IHRyaXNvbXkxMiwgZmlsbD10cmlzb215MTIgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiQWxsIERJQSBwcm90ZW9taWNzIikgKwogIHBwX3NyYSAKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBCQ1JfZ2VuZXMgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIHRyaXNvbXkxMikgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09VFJVRSApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpKSAlPiUKICBnZ3Bsb3QoYWVzKHRyaXNvbXkxMiwgbWVhbl9CQ1IsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCiMjIyBVcHJlZ3VsYXRpb24gZ2VuZSBjaHIxMiBpbiB0cmlzb215IDEyCmBgYHtyfQpwbG90X2Nocm9tb3NvbWVfdGhlbWUgPC0gbGlzdCgKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoLTAuOCwwLjgpKSwKICAgIGZhY2V0X3dyYXAofnBhc3RlKCJjaHJvbW9zb21lIixjaHJvbW9zb21lX25hbWUpLCBzY2FsZXMgPSAiZnJlZV94IiksCiAgICB5bGFiKCJsb2cyIG5vcm0uIHByb3RlaW4gYWJ1bmRhbmNlIiksCiAgICB4bGFiKCJQcm90ZWluIGxvY2F0aW9uIG9uIGNocm9tb3NvbWUiKSwKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkKKQoKQ2hyMTJfUF9wbG90X0RJQV9HZXJtYW55XzEgPC0gCiAgRElBICU+JQogIHNlcGFyYXRlKCBjb2wgPSBQRy5Mb2N1cywgaW50byA9IGMoTkEsICJjaHJvbW9zb21lX25hbWUiLCAic3RhcnRfcG9zaXRpb24iKSAsIHNlcCA9ICI6IiwgcmVtb3ZlID0gRkFMU0UsIGV4dHJhID0gImRyb3AiICkgJT4lCiAgZmlsdGVyKCAhaXMubmEobG9nLm5vcm0uTVMyUXVhbnRpdHkpLCAKICAgICAgICAgIGNocm9tb3NvbWVfbmFtZSAlaW4lIGMoIjEyIiksIGNvaG9ydCA9PSAiR2VybWFueV8xIikgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpLAogICAgICAgICBzdGFydF9wb3NpdGlvbiA9IGFzLm51bWVyaWMoc3RhcnRfcG9zaXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHN0YXJ0X3Bvc2l0aW9uLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9U2FtcGxlKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUsIGFscGhhPTAuMiwgY29sb3I9ImRhcmtncmV5IikgKwogIHN0YXRfc21vb3RoKGdlb209J2xpbmUnLCBhbHBoYT0wLjUsIHNlPUZBTFNFLCBhZXMoY29sb3I9dHJpc29teTEyKSwgc3Bhbj0wLjUsIG1ldGhvZCA9ICJsb2VzcyIpICsKICBwbG90X2Nocm9tb3NvbWVfdGhlbWUgKwogIHBwX3NyYSArCiAgZ2d0aXRsZSgiR2VybWFueV8xIHRyaXNvbXkxMiIpICsKICBnZW9tX3JlY3QoeG1pbiA9IDAsIHltaW49LTAuNzgsIHltYXg9MC43OCwgeG1heD0xMzMyNzUzMDksIGNvbG9yPSJncmF5NDAiLCBzaXplPTEuNSwgIGZpbGw9TkEpCkNocjEyX1BfcGxvdF9ESUFfR2VybWFueV8xICsgIHRoZW1lKGFzcGVjdC5yYXRpbz0wLjQsIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgCgpDaHIxMl9QX3Bsb3RfRElBX0dlcm1hbnlfMiA8LSAKICBESUEgJT4lCiAgc2VwYXJhdGUoIGNvbCA9IFBHLkxvY3VzLCBpbnRvID0gYyhOQSwgImNocm9tb3NvbWVfbmFtZSIsICJzdGFydF9wb3NpdGlvbiIpICwgc2VwID0gIjoiLCByZW1vdmUgPSBGQUxTRSwgZXh0cmEgPSAiZHJvcCIgKSAlPiUKICBmaWx0ZXIoICFpcy5uYShsb2cubm9ybS5NUzJRdWFudGl0eSksIAogICAgICAgICAgY2hyb21vc29tZV9uYW1lICVpbiUgYygiMTIiKSwgY29ob3J0ID09ICJHZXJtYW55XzIiKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMiksCiAgICAgICAgIHN0YXJ0X3Bvc2l0aW9uID0gYXMubnVtZXJpYyhzdGFydF9wb3NpdGlvbikpICU+JQogIGdncGxvdChhZXMoc3RhcnRfcG9zaXRpb24sIGxvZy5ub3JtLk1TMlF1YW50aXR5LCBncm91cD1TYW1wbGUpKSArCiAgZ2VvbV9wb2ludChzaXplPTAuNSwgYWxwaGE9MC4yLCBjb2xvcj0iZGFya2dyZXkiKSArCiAgc3RhdF9zbW9vdGgoZ2VvbT0nbGluZScsIGFscGhhPTAuNSwgc2U9RkFMU0UsIGFlcyhjb2xvcj10cmlzb215MTIpLCBzcGFuPTAuNSwgbWV0aG9kID0gImxvZXNzIikgKwogIHBsb3RfY2hyb21vc29tZV90aGVtZSArCiAgcHBfc3JhICsKICBnZ3RpdGxlKCJHZXJtYW55XzIgdHJpc29teTEyIikgKwogIGdlb21fcmVjdCh4bWluID0gMCwgeW1pbj0tMC43OCwgeW1heD0wLjc4LCB4bWF4PTEzMzI3NTMwOSwgY29sb3I9ImdyYXk0MCIsIHNpemU9MS41LCAgZmlsbD1OQSkKQ2hyMTJfUF9wbG90X0RJQV9HZXJtYW55XzIgKyAgdGhlbWUoYXNwZWN0LnJhdGlvPTAuNCwgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSAKCkNocjEyX1BfcGxvdF9ESUFfR2VybWFueV8zIDwtIAogIERJQSAlPiUKICBzZXBhcmF0ZSggY29sID0gUEcuTG9jdXMsIGludG8gPSBjKE5BLCAiY2hyb21vc29tZV9uYW1lIiwgInN0YXJ0X3Bvc2l0aW9uIikgLCBzZXAgPSAiOiIsIHJlbW92ZSA9IEZBTFNFLCBleHRyYSA9ICJkcm9wIiApICU+JQogIGZpbHRlciggIWlzLm5hKGxvZy5ub3JtLk1TMlF1YW50aXR5KSwgCiAgICAgICAgICBjaHJvbW9zb21lX25hbWUgJWluJSBjKCIxMiIpLCBjb2hvcnQgPT0gIkdlcm1hbnlfMyIpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSwKICAgICAgICAgc3RhcnRfcG9zaXRpb24gPSBhcy5udW1lcmljKHN0YXJ0X3Bvc2l0aW9uKSkgJT4lCiAgZ2dwbG90KGFlcyhzdGFydF9wb3NpdGlvbiwgbG9nLm5vcm0uTVMyUXVhbnRpdHksIGdyb3VwPVNhbXBsZSkpICsKICBnZW9tX3BvaW50KHNpemU9MC41LCBhbHBoYT0wLjIsIGNvbG9yPSJkYXJrZ3JleSIpICsKICBzdGF0X3Ntb290aChnZW9tPSdsaW5lJywgYWxwaGE9MC41LCBzZT1GQUxTRSwgYWVzKGNvbG9yPXRyaXNvbXkxMiksIHNwYW49MC41LCBtZXRob2QgPSAibG9lc3MiKSArCiAgcGxvdF9jaHJvbW9zb21lX3RoZW1lICsKICBwcF9zcmEgKwogIGdndGl0bGUoIkdlcm1hbnlfMyB0cmlzb215MTIiKSArCiAgZ2VvbV9yZWN0KHhtaW4gPSAwLCB5bWluPS0wLjc4LCB5bWF4PTAuNzgsIHhtYXg9MTMzMjc1MzA5LCBjb2xvcj0iZ3JheTQwIiwgc2l6ZT0xLjUsICBmaWxsPU5BKQpDaHIxMl9QX3Bsb3RfRElBX0dlcm1hbnlfMyArICB0aGVtZShhc3BlY3QucmF0aW89MC40LCBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpIAoKQ2hyMTJfUF9wbG90X0RJQV9HZXJtYW55XzJfMyA8LSAKICBESUEgJT4lCiAgc2VwYXJhdGUoIGNvbCA9IFBHLkxvY3VzLCBpbnRvID0gYyhOQSwgImNocm9tb3NvbWVfbmFtZSIsICJzdGFydF9wb3NpdGlvbiIpICwgc2VwID0gIjoiLCByZW1vdmUgPSBGQUxTRSwgZXh0cmEgPSAiZHJvcCIgKSAlPiUKICBmaWx0ZXIoICFpcy5uYShsb2cubm9ybS5NUzJRdWFudGl0eSksIAogICAgICAgICAgY2hyb21vc29tZV9uYW1lICVpbiUgYygiMTIiKSwgY29ob3J0ICVpbiUgYyggIkdlcm1hbnlfMyIsICJHZXJtYW55XzIiICkgKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMiksCiAgICAgICAgIHN0YXJ0X3Bvc2l0aW9uID0gYXMubnVtZXJpYyhzdGFydF9wb3NpdGlvbikpICU+JQogIGdncGxvdChhZXMoc3RhcnRfcG9zaXRpb24sIGxvZy5ub3JtLk1TMlF1YW50aXR5LCBncm91cD1TYW1wbGUpKSArCiAgZ2VvbV9wb2ludChzaXplPTAuNSwgYWxwaGE9MC4yLCBjb2xvcj0iZGFya2dyZXkiKSArCiAgc3RhdF9zbW9vdGgoZ2VvbT0nbGluZScsIGFscGhhPTAuNSwgc2U9RkFMU0UsIGFlcyhjb2xvcj10cmlzb215MTIpLCBzcGFuPTAuNSwgbWV0aG9kID0gImxvZXNzIikgKwogIHBsb3RfY2hyb21vc29tZV90aGVtZSArCiAgcHBfc3JhICsKICBnZ3RpdGxlKCJHZXJtYW55XzIgYW5kIEdlcm1hbnlfMyB0cmlzb215MTIiKSArCiAgZ2VvbV9yZWN0KHhtaW4gPSAwLCB5bWluPS0wLjc4LCB5bWF4PTAuNzgsIHhtYXg9MTMzMjc1MzA5LCBjb2xvcj0iZ3JheTQwIiwgc2l6ZT0xLjUsICBmaWxsPU5BKQpDaHIxMl9QX3Bsb3RfRElBX0dlcm1hbnlfMl8zICsgIHRoZW1lKGFzcGVjdC5yYXRpbz0wLjQsIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgCgpDaHIxMl9QX3Bsb3RfRElBX1N3ZWRlbl8xIDwtIAogIERJQSAlPiUKICBzZXBhcmF0ZSggY29sID0gUEcuTG9jdXMsIGludG8gPSBjKE5BLCAiY2hyb21vc29tZV9uYW1lIiwgInN0YXJ0X3Bvc2l0aW9uIikgLCBzZXAgPSAiOiIsIHJlbW92ZSA9IEZBTFNFLCBleHRyYSA9ICJkcm9wIiApICU+JQogIGZpbHRlciggIWlzLm5hKGxvZy5ub3JtLk1TMlF1YW50aXR5KSwgCiAgICAgICAgICBjaHJvbW9zb21lX25hbWUgJWluJSBjKCIxMiIpLCBjb2hvcnQgPT0gIlN3ZWRlbl8xIikgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpLAogICAgICAgICBzdGFydF9wb3NpdGlvbiA9IGFzLm51bWVyaWMoc3RhcnRfcG9zaXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHN0YXJ0X3Bvc2l0aW9uLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9U2FtcGxlKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUsIGFscGhhPTAuMiwgY29sb3I9ImRhcmtncmV5IikgKwogIHN0YXRfc21vb3RoKGdlb209J2xpbmUnLCBhbHBoYT0wLjUsIHNlPUZBTFNFLCBhZXMoY29sb3I9dHJpc29teTEyKSwgc3Bhbj0wLjUsIG1ldGhvZCA9ICJsb2VzcyIpICsKICBwbG90X2Nocm9tb3NvbWVfdGhlbWUgKwogIHBwX3NyYSArCiAgZ2d0aXRsZSgiU3dlZGVuXzEgdHJpc29teTEyIikgKwogIGdlb21fcmVjdCh4bWluID0gMCwgeW1pbj0tMC43OCwgeW1heD0wLjc4LCB4bWF4PTEzMzI3NTMwOSwgY29sb3I9ImdyYXk0MCIsIHNpemU9MS41LCAgZmlsbD1OQSkKQ2hyMTJfUF9wbG90X0RJQV9Td2VkZW5fMSArICB0aGVtZShhc3BlY3QucmF0aW89MC40LCBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpIAoKQ2hyMTJfUF9wbG90X0RJQV9IaWdoX3Jpc2sgPC0gCiAgRElBICU+JQogIHNlcGFyYXRlKCBjb2wgPSBQRy5Mb2N1cywgaW50byA9IGMoTkEsICJjaHJvbW9zb21lX25hbWUiLCAic3RhcnRfcG9zaXRpb24iKSAsIHNlcCA9ICI6IiwgcmVtb3ZlID0gRkFMU0UsIGV4dHJhID0gImRyb3AiICkgJT4lCiAgZmlsdGVyKCAhaXMubmEobG9nLm5vcm0uTVMyUXVhbnRpdHkpLCAKICAgICAgICAgIGNocm9tb3NvbWVfbmFtZSAlaW4lIGMoIjEyIiksIGNvaG9ydCA9PSAiSGlnaF9yaXNrIikgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpLAogICAgICAgICBzdGFydF9wb3NpdGlvbiA9IGFzLm51bWVyaWMoc3RhcnRfcG9zaXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHN0YXJ0X3Bvc2l0aW9uLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9U2FtcGxlKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUsIGFscGhhPTAuMiwgY29sb3I9ImRhcmtncmV5IikgKwogIHN0YXRfc21vb3RoKGdlb209J2xpbmUnLCBhbHBoYT0wLjUsIHNlPUZBTFNFLCBhZXMoY29sb3I9dHJpc29teTEyKSwgc3Bhbj0wLjUsIG1ldGhvZCA9ICJsb2VzcyIpICsKICBwbG90X2Nocm9tb3NvbWVfdGhlbWUgKwogIHBwX3NyYSArCiAgZ2d0aXRsZSgiSGlnaF9yaXNrIHRyaXNvbXkxMiIpICsKICBnZW9tX3JlY3QoeG1pbiA9IDAsIHltaW49LTAuNzgsIHltYXg9MC43OCwgeG1heD0xMzMyNzUzMDksIGNvbG9yPSJncmF5NDAiLCBzaXplPTEuNSwgIGZpbGw9TkEpCkNocjEyX1BfcGxvdF9ESUFfSGlnaF9yaXNrICsgIHRoZW1lKGFzcGVjdC5yYXRpbz0wLjQsIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgCgpDaHIxMl9QX3Bsb3RfRElBX2FsbCA8LSAKICBESUEgJT4lCiAgc2VwYXJhdGUoIGNvbCA9IFBHLkxvY3VzLCBpbnRvID0gYyhOQSwgImNocm9tb3NvbWVfbmFtZSIsICJzdGFydF9wb3NpdGlvbiIpICwgc2VwID0gIjoiLCByZW1vdmUgPSBGQUxTRSwgZXh0cmEgPSAiZHJvcCIgKSAlPiUKICBmaWx0ZXIoICFpcy5uYShsb2cubm9ybS5NUzJRdWFudGl0eSksIAogICAgICAgICAgY2hyb21vc29tZV9uYW1lICVpbiUgYygiMTIiKSkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpLAogICAgICAgICBzdGFydF9wb3NpdGlvbiA9IGFzLm51bWVyaWMoc3RhcnRfcG9zaXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHN0YXJ0X3Bvc2l0aW9uLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9U2FtcGxlKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUsIGFscGhhPTAuMiwgY29sb3I9ImRhcmtncmV5IikgKwogIHN0YXRfc21vb3RoKGdlb209J2xpbmUnLCBhbHBoYT0wLjUsIHNlPUZBTFNFLCBhZXMoY29sb3I9dHJpc29teTEyKSwgc3Bhbj0wLjUsIG1ldGhvZCA9ICJsb2VzcyIpICsKICBwbG90X2Nocm9tb3NvbWVfdGhlbWUgKwogIHBwX3NyYSArCiAgZ2d0aXRsZSgiVHJpc29teTEyIGFsbCBjb2hvcnRzIikgKwogIGdlb21fcmVjdCh4bWluID0gMCwgeW1pbj0tMC43OCwgeW1heD0wLjc4LCB4bWF4PTEzMzI3NTMwOSwgY29sb3I9ImdyYXk0MCIsIHNpemU9MS41LCAgZmlsbD1OQSkKQ2hyMTJfUF9wbG90X0RJQV9hbGwgKyAgdGhlbWUoYXNwZWN0LnJhdGlvPTAuNCwgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSAKYGBgCgojIyMgRGlmZmVyZW50aWFsbHkgYWJ1bmRhbnQgcHJvdGVpbnMgSGlSSUVGCiMjIyMgVXByZWd1bGF0ZWQgaGl0cwpgYGB7cn0KdXBfaW5fdHJpczEyX2hpdCA8LSAgCiAgbGltbWFfcmVzdWx0cyAlPiUgZmlsdGVyKG11dCA9PSAiY2hyb21fYWJiZXJfdHJpc29teTEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDID4gMCwgaGl0X2Fubm90YXRpb24gPT0gImhpdCIgKSAlPiUKICAuJGdlbmUKCm1lc3NhZ2UocGFzdGUoCkRJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAhPSAiR2VybWFueV8xIiwgIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIHVwX2luX3RyaXMxMl9oaXQgICkgJT4lIC4kUEcuUHJvdGVpbkdyb3VwcyAlPiUgdW5pcXVlICU+JSBsZW5ndGgsCiJvZiB0aGUgdXByZWd1bGF0ZWQgaGl0cyBmb3VuZCBpbiBESUEgZGF0YSIpKQoKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fdHJpczEyX2hpdCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fdXAsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcyIpICsKICBwcF9zcmEgCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fdHJpczEyX2hpdCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fdXAsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCiMjIyMgRG93bnJlZ3VsYXRlZCBoaXRzCmBgYHtyfQpkb3duX2luX3RyaXMxMl9oaXQgPC0gIAogIGxpbW1hX3Jlc3VsdHMgJT4lIGZpbHRlcihtdXQgPT0gImNocm9tX2FiYmVyX3RyaXNvbXkxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dGQyA8IDAsIGhpdF9hbm5vdGF0aW9uID09ICJoaXQiICkgJT4lCiAgLiRnZW5lCgptZXNzYWdlKHBhc3RlKApESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBkb3duX2luX3RyaXMxMl9oaXQgICkgJT4lIC4kUEcuUHJvdGVpbkdyb3VwcyAlPiUgdW5pcXVlICU+JSBsZW5ndGgsCiJvZiB0aGUgZG93bnJlZ3VsYXRlZCBoaXRzIGZvdW5kIGluIERJQSBkYXRhIikpCgpESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBkb3duX2luX3RyaXMxMl9oaXQgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIHRyaXNvbXkxMikgJT4lCiAgc3VtbWFyaXNlKG1lYW5fZG93biA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fZG93biwgZ3JvdXA9IHRyaXNvbXkxMiwgZmlsbD10cmlzb215MTIgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiQWxsIERJQSBwcm90ZW9taWNzIikgKwogIHBwX3NyYSAKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSBkb3duX2luX3RyaXMxMl9oaXQgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIHRyaXNvbXkxMikgJT4lCiAgc3VtbWFyaXNlKG1lYW5fZG93biA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fZG93biwgZ3JvdXA9IHRyaXNvbXkxMiwgZmlsbD10cmlzb215MTIgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgcHBfc3JhICsKICBmYWNldF93cmFwKH5jb2hvcnQpCmBgYAoKCgoKIyMjIyBVcHJlZ3VsYXRlZCBjYW5kaWRhdGVzCmBgYHtyfQp1cF9pbl90cmlzMTJfY2FuZCA8LSAgCiAgbGltbWFfcmVzdWx0cyAlPiUgZmlsdGVyKG11dCA9PSAiY2hyb21fYWJiZXJfdHJpc29teTEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDID4gMCwgaGl0X2Fubm90YXRpb24gJWluJSBjKCAiaGl0IiwgImNhbmRpZGF0ZSIpICkgJT4lCiAgLiRnZW5lCgptZXNzYWdlKHBhc3RlKApESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSB1cF9pbl90cmlzMTJfY2FuZCAgKSAlPiUgLiRQRy5Qcm90ZWluR3JvdXBzICU+JSB1bmlxdWUgJT4lIGxlbmd0aCwKIm9mIHRoZSB1cHJlZ3VsYXRlZCBoaXRzIGZvdW5kIGluIERJQSBkYXRhIikpCgpESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSAgdXBfaW5fdHJpczEyX2NhbmQgICkgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBTYW1wbGUsIGBTYW1wbGUgSURgLCBQYXRfSUQsIHRyaXNvbXkxMikgJT4lCiAgc3VtbWFyaXNlKG1lYW5fdXAgPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIGdncGxvdChhZXModHJpc29teTEyLCBtZWFuX3VwLCBncm91cD0gdHJpc29teTEyLCBmaWxsPXRyaXNvbXkxMiApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJBbGwgRElBIHByb3Rlb21pY3MiKSArCiAgcHBfc3JhIAoKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lICB1cF9pbl90cmlzMTJfY2FuZCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fdXAsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCiMjIyMgRG93bnJlZ3VsYXRlZCBoaXRzCmBgYHtyfQpkb3duX2luX3RyaXMxMl9jYW5kIDwtICAKICBsaW1tYV9yZXN1bHRzICU+JSBmaWx0ZXIobXV0ID09ICJjaHJvbV9hYmJlcl90cmlzb215MTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nRkMgPCAwLCBoaXRfYW5ub3RhdGlvbiAlaW4lIGMoICJoaXQiLCAiY2FuZGlkYXRlIikgKSAlPiUKICAuJGdlbmUKCm1lc3NhZ2UocGFzdGUoCkRJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAhPSAiR2VybWFueV8xIiwgIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIGRvd25faW5fdHJpczEyX2NhbmQgICkgJT4lIC4kUEcuUHJvdGVpbkdyb3VwcyAlPiUgdW5pcXVlICU+JSBsZW5ndGgsCiJvZiB0aGUgZG93bnJlZ3VsYXRlZCBoaXRzIGZvdW5kIGluIERJQSBkYXRhIikpCgpESUEgJT4lIAogIGZpbHRlcihjb2hvcnQgIT0gIkdlcm1hbnlfMSIsICFpcy5uYSh0cmlzb215MTIpLFBHLlByb3RlaW5Hcm91cHMgJWluJSAgZG93bl9pbl90cmlzMTJfY2FuZCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl9kb3duID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09VFJVRSApKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpKSAlPiUKICBnZ3Bsb3QoYWVzKHRyaXNvbXkxMiwgbWVhbl9kb3duLCBncm91cD0gdHJpc29teTEyLCBmaWxsPXRyaXNvbXkxMiApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJBbGwgRElBIHByb3Rlb21pY3MiKSArCiAgcHBfc3JhIAoKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lICBkb3duX2luX3RyaXMxMl9jYW5kICApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCB0cmlzb215MTIpICU+JQogIHN1bW1hcmlzZShtZWFuX2Rvd24gPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIGdncGxvdChhZXModHJpc29teTEyLCBtZWFuX2Rvd24sIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCiMjIyMgVG9wIDEwMCB1cHJlZ3VsYXRlZCBwcm90ZWlucwpgYGB7cn0KdXBfaW5fdHJpczEyXzEwMCA8LSAgCiAgbGltbWFfcmVzdWx0cyAlPiUgZmlsdGVyKG11dCA9PSAiY2hyb21fYWJiZXJfdHJpc29teTEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDID4gMCwgZmRyIDwgMC4xKSAlPiUKICBhcnJhbmdlKGRlc2MobG9nRkMpKSAlPiUKICBkcGx5cjo6c2xpY2UoMToxMDApICU+JSAuJGdlbmUKCm1lc3NhZ2UocGFzdGUoCkRJQSAlPiUgCiAgZmlsdGVyKGNvaG9ydCAhPSAiR2VybWFueV8xIiwgIWlzLm5hKHRyaXNvbXkxMiksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIHVwX2luX3RyaXMxMl8xMDAgICkgJT4lIC4kUEcuUHJvdGVpbkdyb3VwcyAlPiUgdW5pcXVlICU+JSBsZW5ndGgsCiJvZiB0aGUgdG9wIDEwMCB1cHJlZ3VsYXRlZCBwcm90ZWlucyBmb3VuZCBpbiBESUEgZGF0YSIpKQoKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fdHJpczEyXzEwMCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fdXAsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcyIpICsKICBwcF9zcmEgCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgdXBfaW5fdHJpczEyXzEwMCAgKSAlPiUKICBncm91cF9ieShjb2hvcnQsIFNhbXBsZSwgYFNhbXBsZSBJRGAsIFBhdF9JRCwgdHJpc29teTEyKSAlPiUKICBzdW1tYXJpc2UobWVhbl91cCA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPVRSVUUgKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fdXAsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCgojIyMjIFRvcCAxMDAgZG93bnJlZ3VsYXRlZCBwcm90ZWlucwpgYGB7cn0KZG93bl9pbl90cmlzMTJfMTAwIDwtICAKICBsaW1tYV9yZXN1bHRzICU+JSBmaWx0ZXIobXV0ID09ICJjaHJvbV9hYmJlcl90cmlzb215MTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nRkMgPCAwLCBmZHIgPCAwLjEpICU+JQogIGFycmFuZ2UobG9nRkMpICU+JQogIGRwbHlyOjpzbGljZSgxOjEwMCkgJT4lIC4kZ2VuZQoKbWVzc2FnZShwYXN0ZSgKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgZG93bl9pbl90cmlzMTJfMTAwICApICU+JSAuJFBHLlByb3RlaW5Hcm91cHMgJT4lIHVuaXF1ZSAlPiUgbGVuZ3RoLAoib2YgdGhlIHRvcCAxMDAgZG93bnJlZ3VsYXRlZCBwcm90ZWlucyBmb3VuZCBpbiBESUEgZGF0YSIpKQoKRElBICU+JSAKICBmaWx0ZXIoY29ob3J0ICE9ICJHZXJtYW55XzEiLCAhaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgZG93bl9pbl90cmlzMTJfMTAwICApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCB0cmlzb215MTIpICU+JQogIHN1bW1hcmlzZShtZWFuX2Rvd24gPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIGdncGxvdChhZXModHJpc29teTEyLCBtZWFuX2Rvd24sIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkFsbCBESUEgcHJvdGVvbWljcyIpICsKICBwcF9zcmEgCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEodHJpc29teTEyKSxQRy5Qcm90ZWluR3JvdXBzICVpbiUgZG93bl9pbl90cmlzMTJfMTAwICApICU+JQogIGdyb3VwX2J5KGNvaG9ydCwgU2FtcGxlLCBgU2FtcGxlIElEYCwgUGF0X0lELCB0cmlzb215MTIpICU+JQogIHN1bW1hcmlzZShtZWFuX2Rvd24gPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT1UUlVFICkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIGdncGxvdChhZXModHJpc29teTEyLCBtZWFuX2Rvd24sIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHBwX3NyYSArCiAgZmFjZXRfd3JhcCh+Y29ob3J0KQpgYGAKCgojIyBJR0hWIAojIyMgWkFQNzAKYGBge3IsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyMjIyMjIyBHZXJtYW55XzEKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksUEcuUHJvdGVpbkdyb3VwcyA9PSJaQVA3MCIsIGNvaG9ydCA9PSAiR2VybWFueV8xIiAgKSAlPiUKICBtdXRhdGUoSUdIVl9tdXRhdGVkID0gYXMuZmFjdG9yKElHSFZfbXV0YXRlZCkpICU+JQogIGdncGxvdChhZXMoSUdIVl9tdXRhdGVkLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9IElHSFZfbXV0YXRlZCwgZmlsbD1JR0hWX211dGF0ZWQgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiRElBIHByb3Rlb21pY3MgR2VybWFueV8xIikgKwogIHBwX3NyYQoKbWVzc2FnZSgiTnVtYmVyIG9mIE5BcyBESUEgR2VybWFueV8xOiIpCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSwgY29ob3J0ID09ICJHZXJtYW55XzEiLFBHLlByb3RlaW5Hcm91cHMgPT0iWkFQNzAiICApICU+JSAKICBzZWxlY3QoSUdIVl9tdXRhdGVkLCBTYW1wbGUsIGxvZy5ub3JtLk1TMlF1YW50aXR5KSAlPiUgdW5pcXVlICU+JSBncm91cF9ieShJR0hWX211dGF0ZWQpICU+JSBzdW1tYXJpc2UoTkFzPXN1bShpcy5uYShsb2cubm9ybS5NUzJRdWFudGl0eSkpICkKCiMjIyMjIyMjIyMjIyBHZXJtYW55XzIKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksUEcuUHJvdGVpbkdyb3VwcyA9PSJaQVA3MCIsIGNvaG9ydCA9PSAiR2VybWFueV8yIiAgKSAlPiUKICBtdXRhdGUoSUdIVl9tdXRhdGVkID0gYXMuZmFjdG9yKElHSFZfbXV0YXRlZCkpICU+JQogIGdncGxvdChhZXMoSUdIVl9tdXRhdGVkLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9IElHSFZfbXV0YXRlZCwgZmlsbD1JR0hWX211dGF0ZWQgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiRElBIHByb3Rlb21pY3MgR2VybWFueV8yIikgKwogIHBwX3NyYQoKbWVzc2FnZSgiTnVtYmVyIG9mIE5BcyBESUEgR2VybWFueV8yOiIpCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShJR0hWX211dGF0ZWQpLCBjb2hvcnQgPT0gIkdlcm1hbnlfMiIsUEcuUHJvdGVpbkdyb3VwcyA9PSJaQVA3MCIgICkgJT4lIHNlbGVjdChJR0hWX211dGF0ZWQsIFNhbXBsZSwgbG9nLm5vcm0uTVMyUXVhbnRpdHkpICU+JSB1bmlxdWUgJT4lIGdyb3VwX2J5KElHSFZfbXV0YXRlZCkgJT4lIHN1bW1hcmlzZShOQXM9c3VtKGlzLm5hKGxvZy5ub3JtLk1TMlF1YW50aXR5KSkgKQoKIyMjIyMjIyMjIyMjIEdlcm1hbnlfMwpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSxQRy5Qcm90ZWluR3JvdXBzID09IlpBUDcwIiwgY29ob3J0ID09ICJHZXJtYW55XzMiICApICU+JQogIG11dGF0ZShJR0hWX211dGF0ZWQgPSBhcy5mYWN0b3IoSUdIVl9tdXRhdGVkKSkgJT4lCiAgZ2dwbG90KGFlcyhJR0hWX211dGF0ZWQsIGxvZy5ub3JtLk1TMlF1YW50aXR5LCBncm91cD0gSUdIVl9tdXRhdGVkLCBmaWxsPUlHSFZfbXV0YXRlZCApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJESUEgcHJvdGVvbWljcyBHZXJtYW55XzMiKSArCiAgcHBfc3JhCgptZXNzYWdlKCJOdW1iZXIgb2YgTkFzIERJQSBHZXJtYW55XzM6IikKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksIGNvaG9ydCA9PSAiR2VybWFueV8zIixQRy5Qcm90ZWluR3JvdXBzID09IlpBUDcwIiAgKSAlPiUgc2VsZWN0KElHSFZfbXV0YXRlZCwgU2FtcGxlLCBsb2cubm9ybS5NUzJRdWFudGl0eSkgJT4lIHVuaXF1ZSAlPiUgZ3JvdXBfYnkoSUdIVl9tdXRhdGVkKSAlPiUgc3VtbWFyaXNlKE5Bcz1zdW0oaXMubmEobG9nLm5vcm0uTVMyUXVhbnRpdHkpKSApCgoKIyMjIyMjIyMjIyMjIFN3ZWRlbgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSxQRy5Qcm90ZWluR3JvdXBzID09IlpBUDcwIiwgY29ob3J0ID09ICJTd2VkZW5fMSIgICkgJT4lCiAgbXV0YXRlKElHSFZfbXV0YXRlZCA9IGFzLmZhY3RvcihJR0hWX211dGF0ZWQpKSAlPiUKICBnZ3Bsb3QoYWVzKElHSFZfbXV0YXRlZCwgbG9nLm5vcm0uTVMyUXVhbnRpdHksIGdyb3VwPSBJR0hWX211dGF0ZWQsIGZpbGw9SUdIVl9tdXRhdGVkICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkRJQSBwcm90ZW9taWNzIFN3ZWRlbl8xIikgKwogIHBwX3NyYQoKbWVzc2FnZSgiTnVtYmVyIG9mIE5BcyBESUEgU3dlZGVuXzE6IikKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksIGNvaG9ydCA9PSAiU3dlZGVuXzEiLFBHLlByb3RlaW5Hcm91cHMgPT0iWkFQNzAiICApICU+JSBzZWxlY3QoSUdIVl9tdXRhdGVkLCBTYW1wbGUsIGxvZy5ub3JtLk1TMlF1YW50aXR5KSAlPiUgdW5pcXVlICU+JSBncm91cF9ieShJR0hWX211dGF0ZWQpICU+JSBzdW1tYXJpc2UoTkFzPXN1bShpcy5uYShsb2cubm9ybS5NUzJRdWFudGl0eSkpICkKCiMjIyMjIyMjIyMjIyBIaWdoIHJpc2sKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksUEcuUHJvdGVpbkdyb3VwcyA9PSJaQVA3MCIsIGNvaG9ydCA9PSAiSGlnaF9yaXNrIiAgKSAlPiUKICBtdXRhdGUoSUdIVl9tdXRhdGVkID0gYXMuZmFjdG9yKElHSFZfbXV0YXRlZCkpICU+JQogIGdncGxvdChhZXMoSUdIVl9tdXRhdGVkLCBsb2cubm9ybS5NUzJRdWFudGl0eSwgZ3JvdXA9IElHSFZfbXV0YXRlZCwgZmlsbD1JR0hWX211dGF0ZWQgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2JlZXN3YXJtKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiRElBIHByb3Rlb21pY3MgSGlnaF9yaXNrIikgKwogIHBwX3NyYQoKbWVzc2FnZSgiTnVtYmVyIG9mIE5BcyBESUEgSGlnaF9yaXNrOiIpCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShJR0hWX211dGF0ZWQpLCBjb2hvcnQgPT0gIkhpZ2hfcmlzayIsUEcuUHJvdGVpbkdyb3VwcyA9PSJaQVA3MCIgICkgJT4lIHNlbGVjdChJR0hWX211dGF0ZWQsIFNhbXBsZSwgbG9nLm5vcm0uTVMyUXVhbnRpdHkpICU+JSB1bmlxdWUgJT4lIGdyb3VwX2J5KElHSFZfbXV0YXRlZCkgJT4lIHN1bW1hcmlzZShOQXM9c3VtKGlzLm5hKGxvZy5ub3JtLk1TMlF1YW50aXR5KSkgKQoKIyMjIyMjIyMjIyMjIGFsbApESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSxQRy5Qcm90ZWluR3JvdXBzID09IlpBUDcwIiApICU+JQogIG11dGF0ZShJR0hWX211dGF0ZWQgPSBhcy5mYWN0b3IoSUdIVl9tdXRhdGVkKSkgJT4lCiAgZ2dwbG90KGFlcyhJR0hWX211dGF0ZWQsIGxvZy5ub3JtLk1TMlF1YW50aXR5LCBncm91cD0gSUdIVl9tdXRhdGVkLCBmaWxsPUlHSFZfbXV0YXRlZCApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3giKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJESUEgcHJvdGVvbWljcyBhbGwiKSArCiAgcHBfc3JhCgptZXNzYWdlKCJOdW1iZXIgb2YgTkFzIERJQSBhbGwiKQpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSxQRy5Qcm90ZWluR3JvdXBzID09IlpBUDcwIiAgKSAlPiUgc2VsZWN0KElHSFZfbXV0YXRlZCwgU2FtcGxlLCBsb2cubm9ybS5NUzJRdWFudGl0eSkgJT4lIHVuaXF1ZSAlPiUgZ3JvdXBfYnkoSUdIVl9tdXRhdGVkKSAlPiUgc3VtbWFyaXNlKE5Bcz1zdW0oaXMubmEobG9nLm5vcm0uTVMyUXVhbnRpdHkpKSApCmBgYAoKIyMjIEJDUiBwcm90ZWlucwpgYGB7cn0KRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcykgJT4lCiAgZ3JvdXBfYnkoU2FtcGxlLCBJR0hWX211dGF0ZWQsIGNvaG9ydCkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09IFRSVUUpICkgJT4lCiAgbXV0YXRlKElHSFZfbXV0YXRlZCA9IGFzLmZhY3RvcihJR0hWX211dGF0ZWQpKSAlPiUKICBnZ3Bsb3QoYWVzKElHSFZfbXV0YXRlZCwgbWVhbl9CQ1IsIGdyb3VwPSBJR0hWX211dGF0ZWQsIGZpbGw9SUdIVl9tdXRhdGVkICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkJDUiBwcm90ZWluIGFidW5kYW5jZXMgfiBJR0hWIikgKwogIHBwX3NyYQoKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcykgJT4lCiAgZ3JvdXBfYnkoU2FtcGxlLCBJR0hWX211dGF0ZWQsIGNvaG9ydCkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09IFRSVUUpICkgJT4lCiAgbXV0YXRlKElHSFZfbXV0YXRlZCA9IGFzLmZhY3RvcihJR0hWX211dGF0ZWQpKSAlPiUKICBnZ3Bsb3QoYWVzKElHSFZfbXV0YXRlZCwgbWVhbl9CQ1IsIGdyb3VwPSBJR0hWX211dGF0ZWQsIGZpbGw9SUdIVl9tdXRhdGVkICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIGdndGl0bGUoIkJDUiBwcm90ZWluIGFidW5kYW5jZXMgfiBJR0hWIikgKwogIGZhY2V0X3dyYXAofmNvaG9ydCkgKwogIHBwX3NyYQpgYGAKCiMjIElHSFYgKyB0cmlzb215MTIKIyMjIEJDUiBwcm90ZWlucwpgYGB7cn0KRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKElHSFZfbXV0YXRlZCksIWlzLm5hKHRyaXNvbXkxMiksIFBHLlByb3RlaW5Hcm91cHMgJWluJSBCQ1JfZ2VuZXMsIGNvaG9ydCAhPSAiR2VybWFueV8xIikgJT4lCiAgZ3JvdXBfYnkoU2FtcGxlLCBJR0hWX211dGF0ZWQsdHJpc29teTEyLCBjb2hvcnQpICU+JQogIHN1bW1hcmlzZShtZWFuX0JDUiA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPSBUUlVFKSApICU+JQogIG11dGF0ZShJR0hWX211dGF0ZWQgPSBhcy5mYWN0b3IoSUdIVl9tdXRhdGVkKSkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpKSAlPiUKICBnZ3Bsb3QoYWVzKGludGVyYWN0aW9uKElHSFZfbXV0YXRlZCwgdHJpc29teTEyKSwgbWVhbl9CQ1IsIGdyb3VwPSBpbnRlcmFjdGlvbihJR0hWX211dGF0ZWQsIHRyaXNvbXkxMiksIGZpbGw9SUdIVl9tdXRhdGVkICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJCQ1IgcHJvdGVpbiBhYnVuZGFuY2VzIH4gSUdIViArIHRyaXNvbXkxMiIpICsKICBwcF9zcmEKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShJR0hWX211dGF0ZWQpLCFpcy5uYSh0cmlzb215MTIpLCBQRy5Qcm90ZWluR3JvdXBzICVpbiUgQkNSX2dlbmVzKSAlPiUKICBncm91cF9ieShTYW1wbGUsIElHSFZfbXV0YXRlZCwgdHJpc29teTEyLCBjb2hvcnQpICU+JQogIHN1bW1hcmlzZShtZWFuX0JDUiA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPSBUUlVFKSApICU+JQogIG11dGF0ZShJR0hWX211dGF0ZWQgPSBhcy5mYWN0b3IoSUdIVl9tdXRhdGVkKSkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpKSAlPiUKICBnZ3Bsb3QoYWVzKGludGVyYWN0aW9uKElHSFZfbXV0YXRlZCwgdHJpc29teTEyKSwgbWVhbl9CQ1IsIGdyb3VwPSBpbnRlcmFjdGlvbihJR0hWX211dGF0ZWQsIHRyaXNvbXkxMiksIGZpbGw9SUdIVl9tdXRhdGVkICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJCQ1IgcHJvdGVpbiBhYnVuZGFuY2VzIH4gSUdIViArIHRyaXNvbXkxMiIpICsKICBmYWNldF93cmFwKH5jb2hvcnQpICsKICBwcF9zcmEKYGBgCgoKIyMjIyBubyBUUDUzIG9yIGRlbDE3cDEzIGFuZCBubyBQRzUKYGBge3J9CkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYShJR0hWX211dGF0ZWQpLCFpcy5uYSh0cmlzb215MTIpLCBQRy5Qcm90ZWluR3JvdXBzICVpbiUgQkNSX2dlbmVzLCBjb2hvcnQgIT0gIkdlcm1hbnlfMSIsIAogICAgICAgICAoaXMubmEoVFA1MykgfCBUUDUzPT0gMCksIChpcy5uYShkZWwxN3AxMykgfCBkZWwxN3AxMz09IDApLAogICAgICAgICAhU2FtcGxlICVpbiUgKHByZWRfRElBX1BHNSAlPiUgZmlsdGVyKFBHNV9wcmVkaWN0ZWRfa3RzcCA9PSBUUlVFKSAlPiUgLiRTYW1wbGUgKSApICU+JQogIGdyb3VwX2J5KFNhbXBsZSwgSUdIVl9tdXRhdGVkLHRyaXNvbXkxMiwgY29ob3J0KSAlPiUKICBzdW1tYXJpc2UobWVhbl9CQ1IgPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT0gVFJVRSkgKSAlPiUKICBtdXRhdGUoSUdIVl9tdXRhdGVkID0gYXMuZmFjdG9yKElHSFZfbXV0YXRlZCkpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgbXV0YXRlKCJ0cmlzb215MTIgKyBJR0hWIiA9ICBpZl9lbHNlKHRyaXNvbXkxMiA9PTEgJiBJR0hWX211dGF0ZWQgPT0gMSwgInRyaXNvbXkxMiBNLUNMTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHRyaXNvbXkxMiA9PTEgJiBJR0hWX211dGF0ZWQgPT0gMCwgInRyaXNvbXkxMiBVLUNMTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHRyaXNvbXkxMiA9PTAgJiBJR0hWX211dGF0ZWQgPT0gMSwgInd0IE0tQ0xMIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmX2Vsc2UodHJpc29teTEyID09MCAmIElHSFZfbXV0YXRlZCA9PSAwLCAid3QgVS1DTEwiLCAiTkEiKSAgKSApICkgKSAlPiUKICBnZ3Bsb3QoYWVzKGB0cmlzb215MTIgKyBJR0hWYCwgbWVhbl9CQ1IsIGdyb3VwPSBgdHJpc29teTEyICsgSUdIVmAsIGZpbGw9YHRyaXNvbXkxMiArIElHSFZgICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsIAogICAgICAgICAgICAgICAgICAgICBjb21wYXJpc29ucyA9IGxpc3QoIGMoInd0IE0tQ0xMIiwgInd0IFUtQ0xMIiksIGMoICJ0cmlzb215MTIgVS1DTEwiLCAid3QgVS1DTEwiICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCAidHJpc29teTEyIE0tQ0xMIiwgInd0IE0tQ0xMIiApICkgKSArCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNvbG9yc19DQ1BbMTo0XSkgKwogIGdndGl0bGUoIkJDUiBwcm90ZWluIGFidW5kYW5jZXMgfiBJR0hWICsgdHJpc29teTEyIG5vIFBHNSBvciBUUDUzL2RlbDE3cCIpICsKICBwcF9zcmEKCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSwhaXMubmEodHJpc29teTEyKSwgUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcywgY29ob3J0ICE9ICJHZXJtYW55XzEiLCAKICAgICAgICAgIVNhbXBsZSAlaW4lIChwcmVkX0RJQV9QRzUgJT4lIGZpbHRlcihQRzVfcHJlZGljdGVkX2t0c3AgPT0gVFJVRSkgJT4lIC4kU2FtcGxlICkgKSAlPiUKICBncm91cF9ieShTYW1wbGUsIElHSFZfbXV0YXRlZCx0cmlzb215MTIsIGNvaG9ydCkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09IFRSVUUpICkgJT4lCiAgbXV0YXRlKElHSFZfbXV0YXRlZCA9IGFzLmZhY3RvcihJR0hWX211dGF0ZWQpKSAlPiUKICBtdXRhdGUodHJpc29teTEyID0gYXMuZmFjdG9yKHRyaXNvbXkxMikpICU+JQogIG11dGF0ZSgidHJpc29teTEyICsgSUdIViIgPSAgaWZfZWxzZSh0cmlzb215MTIgPT0xICYgSUdIVl9tdXRhdGVkID09IDEsICJ0cmlzb215MTIgTS1DTEwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZfZWxzZSh0cmlzb215MTIgPT0xICYgSUdIVl9tdXRhdGVkID09IDAsICJ0cmlzb215MTIgVS1DTEwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZfZWxzZSh0cmlzb215MTIgPT0wICYgSUdIVl9tdXRhdGVkID09IDEsICJ3dCBNLUNMTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHRyaXNvbXkxMiA9PTAgJiBJR0hWX211dGF0ZWQgPT0gMCwgInd0IFUtQ0xMIiwgIk5BIikgICkgKSApICkgJT4lCiAgZ2dwbG90KGFlcyhgdHJpc29teTEyICsgSUdIVmAsIG1lYW5fQkNSLCBncm91cD0gYHRyaXNvbXkxMiArIElHSFZgLCBmaWxsPWB0cmlzb215MTIgKyBJR0hWYCApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCAKICAgICAgICAgICAgICAgICAgICAgY29tcGFyaXNvbnMgPSBsaXN0KCBjKCJ3dCBNLUNMTCIsICJ3dCBVLUNMTCIpLCBjKCAidHJpc29teTEyIFUtQ0xMIiwgInd0IFUtQ0xMIiApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyggInRyaXNvbXkxMiBNLUNMTCIsICJ3dCBNLUNMTCIgKSApICkgKwogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzA1NzFiMCIsICIjY2EwMDIwIiwgImdyZXkiKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jb2xvcnNfQ0NQWzE6NF0pICsKICBnZ3RpdGxlKCJCQ1IgcHJvdGVpbiBhYnVuZGFuY2VzIH4gSUdIViArIHRyaXNvbXkxMiBubyBQRzUiKSArCiAgcHBfc3JhCgpESUEgJT4lIAogIGZpbHRlcighaXMubmEoSUdIVl9tdXRhdGVkKSwhaXMubmEodHJpc29teTEyKSwgUEcuUHJvdGVpbkdyb3VwcyAlaW4lIEJDUl9nZW5lcywgY29ob3J0ICE9ICJHZXJtYW55XzEiLCAKICAgICAgICAgY29ob3J0ICE9ICJIaWdoX3Jpc2siLAogICAgICAgICAhU2FtcGxlICVpbiUgKHByZWRfRElBX1BHNSAlPiUgZmlsdGVyKFBHNV9wcmVkaWN0ZWRfa3RzcCA9PSBUUlVFKSAlPiUgLiRTYW1wbGUgKSApICU+JQogIGdyb3VwX2J5KFNhbXBsZSwgSUdIVl9tdXRhdGVkLHRyaXNvbXkxMiwgY29ob3J0KSAlPiUKICBzdW1tYXJpc2UobWVhbl9CQ1IgPSBtZWFuKGxvZy5ub3JtLk1TMlF1YW50aXR5LCBuYS5ybT0gVFJVRSkgKSAlPiUKICBtdXRhdGUoSUdIVl9tdXRhdGVkID0gYXMuZmFjdG9yKElHSFZfbXV0YXRlZCkpICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgbXV0YXRlKCJ0cmlzb215MTIgKyBJR0hWIiA9ICBpZl9lbHNlKHRyaXNvbXkxMiA9PTEgJiBJR0hWX211dGF0ZWQgPT0gMSwgInRyaXNvbXkxMiBNLUNMTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHRyaXNvbXkxMiA9PTEgJiBJR0hWX211dGF0ZWQgPT0gMCwgInRyaXNvbXkxMiBVLUNMTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHRyaXNvbXkxMiA9PTAgJiBJR0hWX211dGF0ZWQgPT0gMSwgInd0IE0tQ0xMIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmX2Vsc2UodHJpc29teTEyID09MCAmIElHSFZfbXV0YXRlZCA9PSAwLCAid3QgVS1DTEwiLCAiTkEiKSAgKSApICkgKSAlPiUKICBnZ3Bsb3QoYWVzKGB0cmlzb215MTIgKyBJR0hWYCwgbWVhbl9CQ1IsIGdyb3VwPSBgdHJpc29teTEyICsgSUdIVmAsIGZpbGw9YHRyaXNvbXkxMiArIElHSFZgICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsIAogICAgICAgICAgICAgICAgICAgICBjb21wYXJpc29ucyA9IGxpc3QoIGMoInd0IE0tQ0xMIiwgInd0IFUtQ0xMIiksIGMoICJ0cmlzb215MTIgVS1DTEwiLCAid3QgVS1DTEwiICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCAidHJpc29teTEyIE0tQ0xMIiwgInd0IE0tQ0xMIiApICkgKSArCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNvbG9yc19DQ1BbMTo0XSkgKwogIGdndGl0bGUoIkJDUiBwcm90ZWluIGFidW5kYW5jZXMgfiBJR0hWICsgdHJpc29teTEyIG5vIFBHNSBhbmQgSGlnaCByaXNrIikgKwogIHBwX3NyYQoKRElBICU+JSAKICBmaWx0ZXIoIWlzLm5hKHRyaXNvbXkxMiksIFBHLlByb3RlaW5Hcm91cHMgJWluJSBCQ1JfZ2VuZXMsIGNvaG9ydCAhPSAiR2VybWFueV8xIiwgCiAgICAgICAgICFTYW1wbGUgJWluJSAocHJlZF9ESUFfUEc1ICU+JSBmaWx0ZXIoUEc1X3ByZWRpY3RlZF9rdHNwID09IFRSVUUpICU+JSAuJFNhbXBsZSApICkgJT4lCiAgZ3JvdXBfYnkoU2FtcGxlLCB0cmlzb215MTIsIGNvaG9ydCkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fQkNSID0gbWVhbihsb2cubm9ybS5NUzJRdWFudGl0eSwgbmEucm09IFRSVUUpICkgJT4lCiAgbXV0YXRlKHRyaXNvbXkxMiA9IGFzLmZhY3Rvcih0cmlzb215MTIpKSAlPiUKICBnZ3Bsb3QoYWVzKHRyaXNvbXkxMiwgbWVhbl9CQ1IsIGdyb3VwPSB0cmlzb215MTIsIGZpbGw9dHJpc29teTEyICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9iZWVzd2FybSgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIgKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwNTcxYjAiLCAiI2NhMDAyMCIsICJncmV5IikpICsKICBnZ3RpdGxlKCJCQ1IgcHJvdGVpbiBhYnVuZGFuY2VzIH4gdHJpc29teTEyIG5vIFBHNSIpICsKICBwcF9zcmEKCkRJQSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh0cmlzb215MTIpLCBQRy5Qcm90ZWluR3JvdXBzICVpbiUgQkNSX2dlbmVzLCBjb2hvcnQgIT0gIkdlcm1hbnlfMSIsIAogICAgICAgICAoaXMubmEoVFA1MykgfCBUUDUzPT0gMCksIChpcy5uYShkZWwxN3AxMykgfCBkZWwxN3AxMz09IDApLAogICAgICAgICAhU2FtcGxlICVpbiUgKHByZWRfRElBX1BHNSAlPiUgZmlsdGVyKFBHNV9wcmVkaWN0ZWRfa3RzcCA9PSBUUlVFKSAlPiUgLiRTYW1wbGUgKSApICU+JQogIGdyb3VwX2J5KFNhbXBsZSwgdHJpc29teTEyLCBjb2hvcnQpICU+JQogIHN1bW1hcmlzZShtZWFuX0JDUiA9IG1lYW4obG9nLm5vcm0uTVMyUXVhbnRpdHksIG5hLnJtPSBUUlVFKSApICU+JQogIG11dGF0ZSh0cmlzb215MTIgPSBhcy5mYWN0b3IodHJpc29teTEyKSkgJT4lCiAgZ2dwbG90KGFlcyh0cmlzb215MTIsIG1lYW5fQkNSLCBncm91cD0gdHJpc29teTEyLCBmaWxsPXRyaXNvbXkxMiApKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fYmVlc3dhcm0oKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiICkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDU3MWIwIiwgIiNjYTAwMjAiLCAiZ3JleSIpKSArCiAgZ2d0aXRsZSgiQkNSIHByb3RlaW4gYWJ1bmRhbmNlcyB+IHRyaXNvbXkxMiBubyBQRzUgb3IgVFA1My9kZWwxN3AiKSArCiAgcHBfc3JhCmBgYAoKIyBTZXNzaW9uIEluZm8KYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgpgYGB7ciBrbml0IGV4aXR9CmtuaXRyOjprbml0X2V4aXQoKQpgYGAKCiMgU2F2ZSBpbXBvcnRhbnQgcGxvdHMKYGBge3J9CiNzYXZlKC4uLiwKIyAgICAgZmlsZSA9ICJSRGF0YV9wbG90cy8uLi4uUkRhdGEiKQpgYGA=